使用PHP从fsockopen解析HTTP头?

时间:2012-02-20 12:18:14

标签: php http header fgets

我设置了一个脚本,出于必要的原因,使用fsock获取HTTP Response标头和GET请求的内容。

function checkUrl($host,$url,$port) {
$fp = fsockopen($host, $port, $errno, $errstr, 10);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET $url HTTP/1.1\r\n";
    $out .= "Host: $host\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        $response = fgets($fp, 1024);
        print(substr($response,9,3));
    }
    fclose($fp);
}
}

如果我简单地回应它,我会调用它并获取所有正确的数据。但实际上我需要从函数返回的是HTTP状态代码。

即。 404或200或301等

但是上面的代码确实给出了错误代码,但是当我限制为3个字符时,最后还是有一堆乱码,我不明白!

e.g。

404, 2BM_n: Encype HThe tp-me=srcsrclanstaPre> lanmg=[0][1][2][3][4][5][6][7][8][9][10[11[12 swt.i> ypeeleamiize#99eco#66ade#33izeine#CCize { #66izeeig tmardespath=th=th=th=th=th=th=spardeolordeignign bocol widwidwid col bler> td Sorabl> e> rdeolordespath=th=th= bo spardeoloe="lanSen>

这让我相信我的回答实际上比一个字符串更复杂吗?标题有什么特别之处还是我误解了fgets是如何工作的?任何帮助非常感谢

2 个答案:

答案 0 :(得分:2)

当你迭代标题/响应的每一行时,即使你只对第一行感兴趣。试试这个:

while (!feof($fp)) {
    $response = fgets($fp, 1024);
    $code = substr($response,9,3);
    if (is_numeric($code)) {
        $break;
     }
}

// $code should contain the response code

如果您只对标题感兴趣而不对回复感兴趣,我建议您提出HEAD个请求,而不是GET个。

除非有一个非常令人信服的理由不建议您使用CURL发出此请求,而不是尝试处理PHP应用逻辑中的所有低级内容。

答案 1 :(得分:1)

问题是你打印出每个块的1024个字符的子串而不是第一个。解决方案是不做循环。改变这个:

while (!feof($fp)) {
    $response = fgets($fp, 1024);
    print(substr($response,9,3));
}

就这样:

$response = fgets($fp, 1024);
print(substr($response,9,3));

或者就是这样,真的,因为你只需要前13个字符,而不是前1024个字符:

$response = fgets($fp, 13);
print(substr($response,9,3));