В документации feof()
имеется большое красное предупреждение :
Внимание
Если соединение, открытое fsockopen()
, не было закрыто сервером, feof()
будет зависать. Чтобы обойти это, см. Пример ниже:
Пример # 1 Обработка таймаутов с помощью feof ()
<?php
function safe_feof($fp, &start = NULL) {
$start = microtime(true);
return feof($fp);
}
/* Assuming $fp is previously opened by fsockopen() */
$start = NULL;
$timeout = ini_get('default_socket_timeout');
while(!safe_feof($fp, $start) && (microtime(true) - $start) < $timeout)
{
/* Handle */
}
?>
Кроме того, вы должны только писать или читать из файлового указателя, если он действителен (что вы не делаете, вы просто устанавливаете сообщение об ошибке):
Это приводит ко второму большому красному предупреждению:
Внимание
Если переданный файловый указатель недействителен, вы можете получить бесконечный цикл, потому что feof()
не может вернуть TRUE
.
Лучше было бы:
$result = '';
if ( !$fp = @fsockopen($host, $port, $errno, $errstr, 30) ) {
$rtn['errornumber'] = $errno;
$rtn['errorstring'] = $errstr;
}
else {
fwrite($fp, $out);
while (!@feof($fp)) {
//...
}
fclose($fp);
$result = trim(body);
}
return $result;
Последнее замечание: если вы выполните перенаправление с
if ( ($followRedirects) && (stristr($s, "location:") != false) ) {
$redirect = preg_replace("/location:/i", "", $s);
return httpGet( trim($redirect) );
}
вы никогда не закрываете указатель файла. Я думаю, что лучше это:
if ( ($followRedirects) && (stristr($s, "location:") != false) ) {
$redirect = preg_replace("/location:/i", "", $s);
$result = httpGet( trim($redirect) );
break;
}
// ...
return $result;