【问题标题】:PHP Curl: read incrementallyPHP Curl:增量读取
【发布时间】:2009-09-09 02:06:13
【问题描述】:

我有一个 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 是否有一种方法可以在下载时将数据传递给用户,同时也可以将数据以字符串形式提供给脚本使用。

【问题讨论】:

    标签: php curl


    【解决方案1】:

    这是一个粗略且不完整(但有效)的类,用于测试 CURLOPT_WRITEFUNCTION 选项的使用。根据libcurl documentation,为该选项提供的函数“一旦收到需要保存的数据,就会被 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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用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');
      

      您可以将数据写入浏览器并将其保存为字符串,而不是将数据写入文件并输出“#”。但是,对于大文件,我会谨慎使用后者。

      【讨论】:

        猜你喜欢
        • 2022-06-11
        • 1970-01-01
        • 2020-05-12
        • 1970-01-01
        • 2021-04-02
        • 2011-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多