get headers - PHP - for get_headers($url, 1),是状态码的键*总是*整数


get headers - PHP - for get_headers($url, 1), are the keys for status codes *always* integers?

查看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);

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

(节选自doc)

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

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

(节选自doc)

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设置为什么

同样,在我曾经通过get_headers放置的每个有效URL中(即许多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请求时也是如此——在用preg_match和regex梳理返回数组之后,情况会变得更糟。

(你会发现各种CURL方法甚至更慢,我已经用非常长的url列表对get_headers()进行了测试,所以枪套,臀部射击,伙伴)

如果我知道状态码总是数字索引,那么在通过preg_match运行它们之前,我可以通过忽略所有非整数索引来加快代码的速度。一个URL的差异可能只有几分之一秒,但是当每天都运行这个函数时,这些小片段就会累积起来。

另外(编辑# 1)

我目前只担心最后的 http状态码(和URL),毕竟重定向。我使用类似的方法来获得最终的URL。

似乎在运行

之后
$headers = array_reverse($headers);

则重定向后的最终状态码将始终在$headers[0]中。但是,同样,只有当状态码被数字索引时,这才是确定的事情。

该函数的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;
            }
        }

换句话说,它测试头文件中是否有:,如果有,则按其名称(此处省略)对其进行索引。如果没有:或者没有向$format请求结果,no_name_header会启动并将其添加到return_value中,而不需要显式索引。

所以,是的,状态行应该总是用数字索引。除非服务器将:放入状态行,这是不寻常的。注意,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>

没有包含":"的标准化原因短语,但你永远不会知道,你可能会在野外遇到不符合惯例的外来服务器…

由于响应代码的索引始终为零,因此可以对其进行关联分配并丢弃原始键。

$headers = get_headers($url,1);
$headers['Http-Response'] = $headers[0];
unset($headers[0]);