Я унаследовал фрагмент кода, который использует функцию fetchURL()
ниже для получения данных с URL-адреса. Я только что заметил, что часто feof()
возвращает значение true до того, как будет получена полная страница данных. Я пробовал несколько тестов и, используя CURL
из file_get_contents()
, каждый раз извлекал полную страницу.
Ошибка прерывистая. При 9 вызовах иногда 7 завершаются успешно, а иногда только 4. Определенные 4 из 9 (это запросы на получение только с изменяющейся строкой запроса) всегда завершаются успешно. Я пытался изменить порядок запросы и те же 4 строки запроса по-прежнему всегда успешны, в то время как остальные иногда работают, а иногда нет.
Таким образом, «кажется», что возвращаемые данные могут иметь какое-то отношение к проблеме, но это прерывистый характер это меня обмануло. Данные, возвращаемые в каждом случае, всегда одни и те же (например, каждый раз, когда я делаю вызов со строкой запроса ?SearchString=8502806
, возвращаемая страница содержит одни и те же данные), но иногда полная страница доставляется fgets/feof
, а иногда нет.
У кого-нибудь есть предложения относительно того, что может быть причиной этой ситуации? Большинство других сообщений, которые O видел на эту тему, касаются противоположной проблемы, из-за которой feof()
не возвращает true.
function fetchURL( $url, $ret = 'body' ) {
$url_parsed = parse_url($url);
$host = $url_parsed["host"];
$port = (isset($url_parsed["port"]))?$url_parsed["port"]:'';
if ($port==0)
$port = 80;
$path = $url_parsed["path"];
if ($url_parsed["query"] != "")
$path .= "?".$url_parsed["query"];
$out = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";
$fp = fsockopen($host, $port, $errno, $errstr, 30);
fwrite($fp, $out);
$body = false;
$h = '';
$b = '';
while (!feof($fp)) {
$s = fgets($fp, 1024);
if ( $body )
$b .= $s;
else
$h .= $s;
if ( $s == "\r\n" )
$body = true;
}
fclose($fp);
return ($ret == 'body')?$b:(($ret == 'head')?$h:array($h, $b));
}
feof
на сокетах обычно (всегда?) плохая идея, так как он будет ждать, пока сервер фактически закроет сокет, прежде чем продолжить. По крайней мере, вы также должны отправлять заголовокConnection: close
, но я бы серьезно рекомендовал полностью переписать этот код, потому что он просто плохой (без оскорблений). - person Tom van der Woerdt   schedule 29.03.2013