Make cURL write data as it gets

I have the following php code I found 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);

      

I am trying to download the xml at the specified url and save it to disk. However, it stops at about 80% and never reaches call echo

after call curl_exec

. I'm not sure why, but I believe it is because he is running out of memory. So I would like to ask if it is possible to force curl to write data to a file every time I downloaded let's say 4kb. If this is not possible, can anyone know how to get the xml file stored in url loaded and saved on my disk using php?

Thanks a lot, BEN.

EDIT: This is the code now, it doesn't work. It writes data to a file, but still only about 80% of the document. Maybe this is not because it exceeds memory, but some other reason? I really can't believe it's hard to copy a file from a url to disk ...

    <?

$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);

    ?>

      

+2


source to share


4 answers


The timeout is set to 5 seconds, which may be too short depending on the file size of the document. Try increasing it to 10-15 to make sure it has enough time to complete the transfer.



+3


source


Here's a complete working example:   

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);
}
?>

      



The secret is to set CURLOPT_NOPROGRESS to FALSE and then CURLOPT_BUFFERSIZE will make a callback report for each CURLOPT_BUFFERSIZE byte. The lower the value, the more often it will be reported. It also depends on download speed etc., so don't count on it reporting every X seconds as it will report for every X byte received.

+5


source


There is a CURELOPT_FILE option that allows you to specify a file handler with which the curl should be written. I'm sure it will do the "right" thing and "write" when it reads, avoiding memory issues.

$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);

      

+2


source


curl_setopt CURLOPT_FILE - the file to which the transfer should be written. The default is STDOUT (browser window)

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

+1


source







All Articles