PHP cURL с частичной передачей - PullRequest
2 голосов
/ 18 марта 2011

Мне нужно прочитать с URL, который никогда не завершится.

По существу, существует веб-служба, которая будет хвост файл журнала. Таким образом, он возвращает последние 10 строк файла или около того, и при записи новых строк он отправляет их немедленно. Этот HTTP-запрос продолжается вечно. Если вы нажмете на него своим браузером, вы увидите эти первые 10 строк, и индикатор прогресса вашего браузера продолжит отображать прогресс, даже если ничего не отображается (пока в файл журнала не будет добавлено больше строк).

У меня есть PHP-скрипт, который должен что-то делать с этими строками журнала. То, что я хотел бы сделать, это нажать на этот URL с помощью cURL, загрузить то, что было доступно, и, если файл журнала молчит (т. Е. Больше строк не добавлено) в течение 10 секунд или около того, завершить запрос. Я не могу просто сделать тайм-аут здесь, потому что, если файл журнала занят, он может загружаться довольно непрерывно в течение некоторого периода времени. Однако для большинства журналов запись в них носит периодический характер.

Есть мысли о том, как этого добиться? Я не вижу каких-либо опций cURL, которые могли бы помочь и могут привести к открытию сокета напрямую.


Решение

Благодаря @Christian Sciberras, я смог заставить это работать. Вот некоторый базовый пример кода для всех, кому нужно нечто подобное:

<?php
$ch=curl_init();

curl_setopt($ch, CURLOPT_URL, 'http://www.whatever.com');
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'read_body');
curl_exec($ch);

if ($error=curl_error($ch)) {
    echo "Error: ", $error;
}

function read_body($ch, $string) {
    //Any new line that comes in appears on $string.  Handle it here.
    $length=strlen($string);
    echo $length, " bytes  |  ", $string;
    return $length; //Return the number of bytes that were handled.  Anything other than the length that was sent, and cURL will error out.
}
?>

Также здесь вы можете найти больше информации: http://curl.haxx.se/libcurl/php/examples/callbacks.html

Ответы [ 2 ]

3 голосов
/ 19 марта 2011

Вы можете либо проверить длину и прервать ее после достижения ожидаемой длины, либо использовать тайм-аут или, что еще лучше, оба из них.

Поскольку вы не беспокоились о каком-то коде: P, я посоветую, что вам нужно для достижения того, чего вы хотите. Остальное зависит от вас.

CURLOPT_TIMEOUT - максимальное количество секунд, в течение которых функции cURL могут выполняться.

CURLOPT_WRITEFUNCTION - Имя функции обратного вызова, в которой функция обратного вызова принимает два параметра. Первый - это ресурс cURL, а второй - строка с записываемыми данными. Данные должны быть записаны с использованием этой функции обратного вызова. Должно вернуть точное количество записанных байтов, иначе это не удастся.

По сути, напишите функцию для CURLOPT_WRITEFUNCTION и сделайте так, чтобы, если длина буфера была больше ожидаемого значения, она возвращала 0. Возвращение 0 фактически приводит к сбою CURL, следовательно, закрытие соединения и продолжение вашего сценария.

0 голосов
/ 19 марта 2011

Вы можете использовать CURLOPT_LOW_SPEED_LIMIT и CURLOPT_LOW_SPEED_TIME, чтобы выручить его, только если ничего не появилось в течение определенного времени.

Или вы можете использовать функции мультиинтерфейса, чтобы самостоятельно решать, останавливаться или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...