使用 PHP 从 API 下载 CSV 文件 - URL 不以 .csv 结尾
Downloading a CSV file using PHP from an API - with a URL that doesn't end with .csv
我一直在尝试以两种不同的方式从 API 下载文件,但均未成功:https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today
*注意文件没有以 .csv
结尾,它只是弹出下载
文件的文件。
下载的文件是 .CSV 文件。
我尝试使用 CURL:
// Date looks like this: 2016-01-31
$today = date("Y-m-d");
$output_filename = "test.csv";
$host = "https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, "https://www.example.com");
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
print_r($result); // prints the contents of the collected file before writing..
// the following lines write the contents to a file in the same directory (provided permissions etc)
$fp = fopen($output_filename, 'w');
fwrite($fp, $result);
fclose($fp);
- 通过这段代码,我得到了一个黑色的 test.csv 文件。
- 在 运行 函数 (
print_r($result)
) 之后,我没有在屏幕上打印任何内容
我尝试使用 file_put_contents
函数:
$today = date("Y-m-d");
echo $today;
file_put_contents("", fopen("https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today", 'r'));
// I TRIED THIS ONE TOO:
// file_put_contents("temp.csv", "https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today");
*我得到一个 CSV 文件,其中第一行包含 URL (https://example.com/export/banana/by_date/v4?api_token=666&from=2016-01-31&to=2016-01-31
)。
有人可以帮助我告诉我我这样做是否正确吗? (因为这不是直接 link 到文件,所以我可能工作方式不对)。
这样做的正确方法是什么。
这是众所周知的(对我而言)从 php 使用 cURL 访问 https 资源的问题 - 它无法在默认配置中验证证书。让这个脚本工作最简单的事情,你应该为 curl_config 添加两行:
$today = date("Y-m-d");
$output_filename = "test.csv";
$host = "https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today";
$ch = curl_init();
$curl_config = [
CURLOPT_URL => $host,
CURLOPT_VERBOSE => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_AUTOREFERER => false,
CURLOPT_REFERER => "https://www.example.com",
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HEADER => 0,
CURLOPT_SSL_VERIFYHOST => 0, //do not verify that host matches one in certifica
CURLOPT_SSL_VERIFYPEER => 0, //do not verify certificate's meta
];
curl_setopt_array($ch, $curl_config); //apply config
$result = curl_exec($ch);
if (empty($result)){
echo curl_error($ch); //show possible error if answer if empty and exit script
exit;
}
curl_close($ch);
print_r($result); // prints the contents of the collected file before writing..
// the following lines write the contents to a file in the same directory (provided permissions etc)
file_put_contents($output_filename, $result);
目标 url 是 https
因此您可能需要添加特定的 ssl 选项
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 );
curl_setopt( $ch, CURLOPT_CAINFO, realpath( '/path/to/cacert.pem' ) );
curl 请求失败的另一个常见原因是缺少用户代理字符串。
curl_setopt( $ch, CURLOPT_USERAGENT, 'my useragent string' );
您可以通过设置 $context
的选项来设置使用 file_get_contents
时的类似选项
根据您最后的评论,添加:
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, TRUE );
我一直在尝试以两种不同的方式从 API 下载文件,但均未成功:https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today
*注意文件没有以 .csv
结尾,它只是弹出下载
文件的文件。
下载的文件是 .CSV 文件。
我尝试使用 CURL:
// Date looks like this: 2016-01-31
$today = date("Y-m-d");
$output_filename = "test.csv";
$host = "https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, "https://www.example.com");
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
print_r($result); // prints the contents of the collected file before writing..
// the following lines write the contents to a file in the same directory (provided permissions etc)
$fp = fopen($output_filename, 'w');
fwrite($fp, $result);
fclose($fp);
- 通过这段代码,我得到了一个黑色的 test.csv 文件。
- 在 运行 函数 (
print_r($result)
) 之后,我没有在屏幕上打印任何内容
我尝试使用 file_put_contents
函数:
$today = date("Y-m-d");
echo $today;
file_put_contents("", fopen("https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today", 'r'));
// I TRIED THIS ONE TOO:
// file_put_contents("temp.csv", "https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today");
*我得到一个 CSV 文件,其中第一行包含 URL (https://example.com/export/banana/by_date/v4?api_token=666&from=2016-01-31&to=2016-01-31
)。
有人可以帮助我告诉我我这样做是否正确吗? (因为这不是直接 link 到文件,所以我可能工作方式不对)。 这样做的正确方法是什么。
这是众所周知的(对我而言)从 php 使用 cURL 访问 https 资源的问题 - 它无法在默认配置中验证证书。让这个脚本工作最简单的事情,你应该为 curl_config 添加两行:
$today = date("Y-m-d");
$output_filename = "test.csv";
$host = "https://example.com/export/banana/by_date/v4?api_token=666&from=$today&to=$today";
$ch = curl_init();
$curl_config = [
CURLOPT_URL => $host,
CURLOPT_VERBOSE => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_AUTOREFERER => false,
CURLOPT_REFERER => "https://www.example.com",
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HEADER => 0,
CURLOPT_SSL_VERIFYHOST => 0, //do not verify that host matches one in certifica
CURLOPT_SSL_VERIFYPEER => 0, //do not verify certificate's meta
];
curl_setopt_array($ch, $curl_config); //apply config
$result = curl_exec($ch);
if (empty($result)){
echo curl_error($ch); //show possible error if answer if empty and exit script
exit;
}
curl_close($ch);
print_r($result); // prints the contents of the collected file before writing..
// the following lines write the contents to a file in the same directory (provided permissions etc)
file_put_contents($output_filename, $result);
目标 url 是 https
因此您可能需要添加特定的 ssl 选项
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 );
curl_setopt( $ch, CURLOPT_CAINFO, realpath( '/path/to/cacert.pem' ) );
curl 请求失败的另一个常见原因是缺少用户代理字符串。
curl_setopt( $ch, CURLOPT_USERAGENT, 'my useragent string' );
您可以通过设置 $context
file_get_contents
时的类似选项
根据您最后的评论,添加:
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, TRUE );