1

查看 get_headers()的PHP 文档...

array get_headers ( string $url [, int $format = 0 ] )

...有两种方法可以运行它:

#1 ( format === 0)

$headers = get_headers($url);

// or

$headers = get_headers($url, 0);

#2 ( format !== 0)

$headers = get_headers($url, 1);

两者之间的区别在于数组是否被数字索引(第一种情况)......

(摘自文档

Array
(
    [0] => HTTP/1.1 200 OK
    [1] => Date: Sat, 29 May 2004 12:28:13 GMT
    [2] => Server: Apache/1.3.27 (Unix)  (Red-Hat/Linux)
    ... etc

...或用键索引(第二种情况)...

(摘自文档

Array
(
    [0] => HTTP/1.1 200 OK
    [Date] => Sat, 29 May 2004 12:28:14 GMT
    [Server] => Apache/1.3.27 (Unix)  (Red-Hat/Linux)
    [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT
    ... etc

在文档中给出的示例中,http 状态代码属于数字索引...

[0] => HTTP/1.1 200 OK

...无论format设置为什么。

同样,在我曾经通过的每个有效 URL get_headers(即许多 URL)中,状态代码始终位于数字索引下,即使存在多个状态代码......

// Output from JSON.stringify(get_headers($url, 1))

{
    "0": "HTTP/1.1 301 Moved Permanently",
    "1": "HTTP/1.1 200 OK",
    "Date": [
        "Thu, 11 Aug 2016 07:12:28 GMT",
        "Thu, 11 Aug 2016 07:12:28 GMT"
    ],
    "Content-Type": [
        "text/html; charset=iso-8859-1",
        "text/html; charset=UTF-8"
    ]
    ... etc

但是,我没有(阅读:不能)在每种类型的服务器上测试每个 URL,因此不能绝对地谈论状态代码索引。

是否有get_headers($url, 1)可能返回非数字 http 状态代码索引?还是硬编码到函数中以始终在数字索引下返回状态代码-无论如何?


额外阅读,对上述问题来说不是必需的或必不可少的......

对于好奇的人,我的问题主要与优化有关。get_headers()已经非常缓慢了——即使发送 HEAD 请求而不是 GET ——并且在将返回数组与 apreg_match和正则表达式结合后只会变得更糟。

(你会发现的各种CURL方法甚至更慢,我已经get_headers()用很长的 URL 列表对它们进行了测试,所以请把那个臀部射击,搭档)

如果我知道状态代码总是以数字索引,那么我可以通过忽略所有非整数索引来加快我的代码速度,然后再通过preg_match. 一个 URL 的差异可能只有几分之一秒,但是当整天运行这个函数时,每天,这些小部分加起来。

另外(编辑#1)

在所有重定向之后,我目前只担心最终的http 状态代码(和 URL)。我正在使用与此类似的方法获取最终 URL。

似乎运行后

$headers = array_reverse($headers);

那么重定向后的最终状态码将始终在$headers[0]. 但是,再一次,如果状态代码是数字索引的,这只是确定的事情。

4

2 回答 2

3

该函数的 PHP C 源代码如下所示:

        if (!format) {
no_name_header:
            add_next_index_str(return_value, zend_string_copy(Z_STR_P(hdr)));
        } else {
            char c;
            char *s, *p;

            if ((p = strchr(Z_STRVAL_P(hdr), ':'))) {
                ... omitted ...
            } else {
                goto no_name_header;
            }
        }

换句话说,它测试:标题中是否有 a,如果有,则继续按其名称对其进行索引(此处省略)。如果没有:或者您没有请求$format结果,no_name_header则启动并将其添加到return_value无显式索引中。

所以,是的,状态行应该总是用数字索引。除非服务器将 a:放入状态行,否则这是不寻常的。请注意,RFC 2616并未明确禁止在状态行:原因短语部分中使用:

Status-Line    = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

Reason-Phrase  = *<TEXT, excluding CR, LF>

TEXT           = <any OCTET except CTLs,
                 but including LWS>

没有包含“:”的标准化原因短语,但你永远不知道,你可能会在野外遇到不符合惯例的异国服务器......</p>

于 2016-08-11T08:18:40.273 回答
0

由于响应代码始终为零索引,因此您可以关联地分配它并丢弃原始键。

$headers = get_headers($url,1);
$headers['Http-Response'] = $headers[0];
unset($headers[0]);
于 2018-11-29T18:22:39.910 回答