function httpGet( $url, $followRedirects=true ) {
global $final_url;
$url_parsed = parse_url($url);
if ( empty($url_parsed['scheme']) ) {
$url_parsed = parse_url('http://'.$url);
}
$final_url = $url_parsed;
$port = $url_parsed["port"];
if ( !$port ) {
$port = 80;
}
$rtn['url']['port'] = $port;
$path = $url_parsed["path"];
if ( empty($path) ) {
$path="/";
}
if ( !empty($url_parsed["query"]) ) {
$path .= "?".$url_parsed["query"];
}
$rtn['url']['path'] = $path;
$host = $url_parsed["host"];
$foundBody = false;
$out = "GET $path HTTP/1.0\r\n";
$out .= "Host: $host\r\n";
$out .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\r\n";
$out .= "Connection: Close\r\n\r\n";
if ( !$fp = @fsockopen($host, $port, $errno, $errstr, 30) ) {
$rtn['errornumber'] = $errno;
$rtn['errorstring'] = $errstr;
}
fwrite($fp, $out);
while (!@feof($fp)) {
$s = @fgets($fp, 128);
if ( $s == "\r\n" ) {
$foundBody = true;
continue;
}
if ( $foundBody ) {
$body .= $s;
} else {
if ( ($followRedirects) && (stristr($s, "location:") != false) ) {
$redirect = preg_replace("/location:/i", "", $s);
return httpGet( trim($redirect) );
}
$header .= $s;
}
}
fclose($fp);
return(trim($body));
}
这段代码有时会无限循环。这有什么不对?
答案 0 :(得分:3)
feof()
documentation中有一个大的红色警告框:
警告强>
如果服务器未关闭
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;
答案 1 :(得分:0)
feof将返回false。
答案 2 :(得分:0)
function httpGet( $url, $followRedirects=true ) {
[...]
return httpGet( trim($redirect) );
}
没有什么可以阻止您一次又一次地获取相同的URL。