PHP - для get_headers($url, 1) ключи для кодов состояния * всегда * целые?

Глядя на PHP документы для get_headers ()...

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 - и ухудшается только после прохождения массива возврата с помощью preg_match и регулярное выражение

(Различные методы CURL вы найдете еще медленнее, я проверял их get_headers() с очень длинными списками URL, так что кобура, что хип-шот, партнер)

Если я знаю, что коды состояния всегда численно индексируются, то я могу немного ускорить мой код, игнорируя все нецелые индексы, прежде чем запускать их через preg_match, Разница для одного URL может составлять доли секунды, но при запуске этой функции весь день, каждый день, эти маленькие кусочки складываются.

Дополнительно (Правка № 1)

В настоящее время меня беспокоит только окончательный код статуса http (и URL) после всех перенаправлений. Я использовал метод, похожий на этот, чтобы получить окончательный URL.

Кажется, что после запуска

$headers = array_reverse($headers);

тогда окончательный код состояния после перенаправления всегда будет в $headers[0], Но, опять же, это только то, что коды статуса имеют цифровую индексацию.

2 ответа

Решение

Исходный код 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]);
Другие вопросы по тегам