Глядя на PHP документы для get_headers ()…
array get_headers ( string $url [, int $format = 0 ] )
… Есть два способа запустить его:
format === 0
)$headers = get_headers($url);
// or
$headers = get_headers($url, 0);
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]
, Но, опять же, это только то, что коды статуса имеют цифровую индексацию.
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]);