PHP:获取头信息并设置临时流上下文

8

我猜测PHP的get_headers函数不允许使用上下文,所以我必须更改默认流上下文仅获取请求的头信息。这会导致页面上的其他请求出现一些问题。我似乎无法弄清如何重置默认流上下文。我尝试了以下代码:

$default = stream_context_get_default(); //Get default stream context so we can reset it
stream_context_set_default( //Only fetch the HEAD
      array(
    'http' => array(
       'method' => 'HEAD'
     )
  )
);
$headers = get_headers($url, 1); //Url can be whatever you want it to be
//var_dump($headers);
var_dump($default);
stream_context_set_default($default); //This doesn't work as it expects an array and not a resource pointer

有人知道如何修复这个问题吗?

我知道有人建议使用Curl,但我不太想用它来解决这个问题。谢谢!


get_headers不一致性:https://dev59.com/jmnWa4cB1Zd3GeqPzVRY - Baba
4个回答

10

最终我使用了stream_get_meta_data()函数获取HTTP头。

以下是我的实现方法:

function get_headers_with_stream_context($url, $context, $assoc = 0) {
    $fp = fopen($url, 'r', null, $context);
    $metaData = stream_get_meta_data($fp);
    fclose($fp);

    $headerLines = $metaData['wrapper_data'];

    if(!$assoc) return $headerLines;

    $headers = array();
    foreach($headerLines as $line) {
        if(strpos($line, 'HTTP') === 0) {
            $headers[0] = $line;
            continue;
        }

        list($key, $value) = explode(': ', $line);
        $headers[$key] = $value;
    }

    return $headers;
}

像这样调用:

$context = stream_context_create(array('http' => array('method' => 'HEAD')));
$headers = get_headers_with_stream_context($url, $context, 1);

它可以给你想要的内容,同时保持标准的stream_context不被修改。

请注意,如果传递的不是http url,此函数将失败。

似乎有一个关于为get_headers()添加附加参数的功能请求,但在我写这篇文章时,错误跟踪器已经关闭,因此无法在那里检查其他解决方案。


5

我曾经遇到类似的问题,但是我使用了带有自定义流上下文的file_get_contents函数。

这是我实现的方法:

$options = array(
               'http' => array(
                     'method' => 'HEAD',
                     'follow_location' => 0
                )
           );

$context = stream_context_create($options);

@file_get_contents($url, NULL, $context);

var_dump($http_response_header);

使用这个上下文,只有标头会被file_get_contents获取,并将填充PHP变量$http_response_header


1

与接受的答案不同,我采用了以下做法,适用于PHP 5.3及以上版本,尽管我还没有完全测试过。(还有一个stream_context_get_params($context),但我认为这已经足够了。)

$stream_context_defaults = stream_context_get_options(stream_context_get_default());
stream_context_set_default(
    array(
        'http' => array(
            'method' => 'HEAD'
        )
    )
);
for ($i = 1; $i <= 10; $i++) {
    $headers = get_headers('http://www.example.org');
}
stream_context_set_default($stream_context_defaults); // reset to defaults

1
这并不总是有效的,“stream_context_set_default()”无法使用空的$stream_context_defaults数组进行“重置”。 - powtac
1
这个有文档记录吗?我发帖是为了尝试解决get_headers缺少参数的问题。我知道设置默认值可能不是最明智的选择,而应该创建一个新的上下文,但我想重用get_headers方法。如果get_headers能像file_get_contents一样具有传递自定义上下文的功能就好了。 - Louis St-Amour
在文档中没有清楚地看到它。通过测试找到了答案。 - powtac

0

从PHP 7.1.0开始,get_headers()现在接受第三个参数作为上下文。

$context = stream_context_create(
    array(
        'http' => array('method' => 'HEAD')
    )
);

$headers = get_headers($url, true, $context);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接