我有一个PHP脚本,它应该接收一个URL并在数据库中搜索URL的缓存版本。如果找到它,它会将缓存版本打印出来给用户,否则它会使用cURL下载并回复给用户。目前,下载脚本如下所示:
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
// grab URL and pass it to the browser
$data = curl_exec($ch);
$mimetype = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
// close cURL resource, and free up system resources
curl_close($ch);
mysql_query("INSERT INTO `cache_files` (`key`, `original_url`, `file_data`, `mime_type`) VALUES (".
"'" . mysql_real_escape_string($key) . "', " .
"'" . mysql_real_escape_string($url) . "', " .
"'" . mysql_real_escape_string($data) . "', " .
"'" . mysql_real_escape_string($mimetype) . "')"
);
if (isset($_GET["no_output"])) die;
header ("Content-Type: " . $mimetype);
header ('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + 157680000), true);
header ('Last-Modified: '.gmdate('D, d M Y H:i:s \G\M\T'), true);
header ('Cache-Control: public; max-age=157680000');
header ('Pragma: ');
print $data;
这当前工作正常,但是,大文件在100%下载之前不会发送给最终用户,这会导致不会触发增量渲染。我想知道cURL是否可以在下载时将数据传递给用户,还可以在字符串中使用数据供脚本使用。
答案 0 :(得分:2)
这是一个粗略且不完整(但工作)的类,用于测试CURLOPT_WRITEFUNCTION选项的使用。根据{{3}},只要收到需要保存的数据,libcurl就会调用此选项给出的函数。因此curl接收的内容应该在收到时传递给服务器。当它实际显示时,当然会依赖于服务器和浏览器。
$url = 'http://stackoverflow.com/';
$curl_test = new CurlCallbackTest($url);
file_put_contents('some.file', $curl_test->content);
class CurlCallbackTest
{
public $content = '';
public function __construct($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'showContent'));
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);
}
private function showContent($ch, $data)
{
$this->setContent($data);
echo htmlspecialchars($data);
return strlen($data);
}
private function setContent($data)
{
$this->content .= $data;
}
}
答案 1 :(得分:1)
您可以使用CURLOPT_WRITEFUNCTION
回调来挂钩cURL的响应数据处理。示例(通过http://www.php.net/manual/en/function.curl-setopt.php#26239):
<?php
function myPoorProgressFunc($ch, $str) {
global $fd;
$len = fwrite($fd, $str);
print('#');
return $len;
}
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'myPoorProgressFunc');
而不是将数据写入文件并输出“#”,您可以将数据写入浏览器并将其保存为字符串。但是,对于大文件,我会对后者持谨慎态度。