PEAR::HTTP/Request2没有';t遵循重定向


PEAR::HTTP/Request2 doesn't follow redirect

报废时,例如。http://baidu.com,脚本不遵循<meta.. refresh..>重定向。我正在运行的代码:

require_once 'HTTP/Request2.php';
$request = new HTTP_Request2("http://baidu.com", HTTP_Request2::METHOD_GET);
$request->setConfig(array(
    'adapter' => 'HTTP_Request2_Adapter_Curl',
    'connect_timeout' => 15,
    'timeout' => 30,
    'follow_redirects' => TRUE,
    'max_redirects' => 10,
));
try {
    $response = $request->send();
    if (200 == $response->getStatus()) {
        $html = $response->getBody();
    } else {
        echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
        $response->getReasonPhrase();
    }
} catch (HTTP_Request2_Exception $e) {
    echo 'Error: ' . $e->getMessage();
}
print $html;

输出:

<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>

有没有办法让它遵循这个重定向,在$response->getBody()中获得正确的html?

PEAR库确实遵循HTTP重定向,因为这些重定向是在请求头中声明的。您在问题中展示的示例是HTML元刷新,这是一种不同的机制。

您要做的是读取对通过PEAR发出的HTTP请求的响应,解析"元刷新"标记,然后对您设法从第一个请求中提取的URI发出第二个请求。

下面是一个函数的示例,它将从PHP手册上留下的注释中执行此操作。

function getUrlContents($url, $maximumRedirections = null, $currentRedirection = 0)
{
 $result = false;
$contents = @file_get_contents($url);
// Check if we need to go somewhere else
if (isset($contents) && is_string($contents))
{
    preg_match_all('/<['s]*meta['s]*http-equiv="?REFRESH"?' . '['s]*content="?[0-9]*;['s]*URL['s]*=['s]*([^>"]*)"?' . '['s]*['/]?['s]*>/si', $contents, $match);
    if (isset($match) && is_array($match) && count($match) == 2 && count($match[1]) == 1)
    {
        if (!isset($maximumRedirections) || $currentRedirection < $maximumRedirections)
        {
            return getUrlContents($match[1][0], $maximumRedirections, ++$currentRedirection);
        }
        $result = false;
    }
    else
    {
        $result = $contents;
    }
}
return $contents;
}

此片段可在以下位置找到:http://php.net/manual/en/function.get-meta-tags.php

正如我所解释的,你可以做以下事情:

//get the url from the meta redirect tag
$url = getUrlContents($site1);
//set up the new request in PEAR
$request = new HTTP_Request2($url, HTTP_Request2::METHOD_GET);

如果这是进行HTTP调用的首选方法,那么您可能需要重新实现getURLContents函数,以便它使用PEAR来获取第一个URL。