Заставить cURL записывать данные по мере их получения

У меня есть следующий php-код, который я нашел здесь:

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 записывать данные в файл каждый раз, когда он загружается, скажем, 4 КБ. Если это невозможно, кто-нибудь знает способ получить файл xml, хранящийся по URL-адресу, загруженному и сохраненному на моем диске с помощью php?

Большое спасибо, БЕН.

EDIT: это код сейчас, он не работает. Он записывает данные в файл, но по-прежнему составляет только около 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);

    ?>

person Benjamin Egelund-Müller    schedule 05.10.2009    source источник
comment
попробуйте 1: добавить ; после fopen 2: fclose файл   -  person Fluffy    schedule 05.10.2009
comment
и 3: увеличьте время ожидания примерно до 300 секунд, потому что страница, на которую вы ссылаетесь, действительно большая.   -  person Fluffy    schedule 05.10.2009
comment
Только что увидел ; проблема, и я обновил код. Он все еще останавливается в том же месте (около 80%), и теперь я пытаюсь запустить скрипт с тайм-аутом 300   -  person Benjamin Egelund-Müller    schedule 05.10.2009
comment
Я установил тайм-аут на 300, но он все еще останавливается в одном и том же месте.   -  person Benjamin Egelund-Müller    schedule 05.10.2009
comment
Ну, я играл с этой и другими возможностями, и ничего не получалось. Я нахожу это невероятным, я не могу загрузить файл с URL-адреса. Тем не менее, спасибо за все ответы здесь. Я буду продолжать бороться и, конечно, если кто-нибудь найдет решение, пожалуйста, напишите его! Когда я найду решение, я, конечно, опубликую его здесь.   -  person Benjamin Egelund-Müller    schedule 05.10.2009


Ответы (3)


Время ожидания установлено на 5 секунд, что может быть слишком коротким в зависимости от размера файла документа. Попробуйте увеличить его до 10-15, чтобы убедиться, что у него достаточно времени для завершения передачи.

person Jesse Dearing    schedule 05.10.2009

Существует параметр CURELOPT_FILE, который позволяет вам указать файл, обработчик, в который должен выполнять запись curl. Я почти уверен, что он будет делать «правильные» вещи и «записывать» при чтении, избегая проблем с памятью.

$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);
person Alan Storm    schedule 05.10.2009
comment
Я добавил к своему исходному сообщению. Это не работает. Код даже не выполняется, я не знаю, где ошибка. - person Benjamin Egelund-Müller; 05.10.2009

curl_setopt CURLOPT_FILE — файл, в который должна быть записана передача. По умолчанию используется STDOUT (окно браузера).

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

person Fluffy    schedule 05.10.2009
comment
Просто интересно: вы случайно не знаете, записывает ли cURL данные в файл по мере их получения или происходит какая-то буферизация? - person Nicolas; 05.10.2009
comment
Несмотря на то, что я сделал это (см. код в первом сообщении, я его отредактировал), это не работает. - person Benjamin Egelund-Müller; 05.10.2009