代码之家  ›  专栏  ›  技术社区  ›  Benjamin Egelund-Müller

使curl在接收数据时写入数据

  •  2
  • Benjamin Egelund-Müller  · 技术社区  · 15 年前

    我找到了下面的PHP代码 here 以下内容:

    function download_xml()
    {
        $url = 'http://tv.sygko.net/tv.xml';
    
        $ch = curl_init($url);
        $timeout = 5;
    
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    
        $data = curl_exec($ch);
    
        echo("curl_exec was succesful"); //This never gets called
    
        curl_close($ch);
        return $data;
    }
    
    $my_file = 'tvdata.xml';
    $handle = fopen($my_file, 'w');
    $data = download_xml();
    fwrite($handle, $data);
    

    我要做的是将XML下载到指定的URL并保存到磁盘上。然而,一旦完成80%左右,它就会停止,并且永远不会到达 echo 呼叫后 curl_exec 呼叫。我不知道为什么,但我相信这是因为它耗尽了记忆。因此,我想问一下,是否可以让curl在每次下载时,比如说4KB,将数据写到文件中。如果这是不可能的,是否有人知道一种方法,可以使用php下载XML文件并将其存储在我的磁盘上?

    非常感谢, 本。

    编辑: 这就是现在的代码,它不起作用。它将数据写入文件,但仍然只有大约80%的文档。也许不是因为它超出了记忆,而是其他原因?我真的不敢相信把一个文件从一个URL复制到光盘上这么困难…

        <?
    
    $url = 'http://tv.sygko.net/tv.xml';
    $my_file = fopen('tvdata.xml', 'w');
    
    $ch = curl_init($url);
    $timeout = 300;
    
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FILE, $my_file);
    curl_setopt($ch, CURLOPT_FAILONERROR, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_BUFFERSIZE, 4096);
    
    curl_exec($ch) OR die("Error in curl_exec()");
    
    echo("got to after curl exec");
    
    fclose($my_file);
    curl_close($ch);
    
        ?>
    
    4 回复  |  直到 12 年前
        1
  •  3
  •   user18044    15 年前

    超时设置为5秒,根据文档的文件大小,这可能太短。尝试将其增加到10-15,以确保有足够的时间完成传输。

        2
  •  5
  •   Joe    12 年前

    下面是一个完全有效的例子:

    public function saveFile($url, $dest) {
    
            if (!file_exists($dest))
                    touch($dest);
    
            $file = fopen($dest, 'w');
            $ch = curl_init();
    
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progressCallback');
            curl_setopt($ch, CURLOPT_BUFFERSIZE, (1024*1024*512));
            curl_setopt($ch, CURLOPT_NOPROGRESS, FALSE);
            curl_setopt($ch, CURLOPT_FAILONERROR, 1);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, 15);
            curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13');
            curl_setopt($ch, CURLOPT_FILE, $file);
    
            curl_exec($ch);
            curl_close($ch);
    
            fclose($file);
    }
    ?>
    

    秘密在于将curlopt_noprogress设置为false,然后,curlopt_bufferSize将为达到的每个curlopt_bufferSize字节生成回调报告。值越小,报告的频率越高。这还取决于您的下载速度等,所以不要指望它每X秒报告一次,因为它将每接收/传输X字节报告一次。

        3
  •  2
  •   Alana Storm    15 年前

    有一个名为curelopt_文件的选项,允许您指定一个文件 处理程序 那卷应该写下来。我很肯定它会做“正确”的事情,读的时候会“写”,避免你的记忆问题。

    $file = fopen('test.txt', 'w'); //<--------- file handler
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,'http://example.com');
    curl_setopt($ch, CURLOPT_FAILONERROR,1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    curl_setopt($ch, CURLOPT_FILE, $file);   //<------- this is your magic line
    curl_exec($ch); 
    curl_close($ch);
    fclose($file);
    
        4
  •  1
  •   Fluffy    15 年前

    curl_setopt curlpt_文件-传输应该写入的文件。默认值为stdout(浏览器窗口)

    http://us2.php.net/manual/en/function.curl-setopt.php