PHP 8.4: Новые функции http_(get|clear)_last_response_headers

Источник: «PHP 8.4: New http_(get|clear)_last_response_headers functions»
В PHP 8.4 добавлены две новые функции http_get_last_response_headers и http_clear_last_response_headers, которые можно использовать для получения и очистки HTTP-заголовков последнего ответа HTTP-обёртки, что может заменить историческую переменную $http_response_header.

PHP предоставляет HTTP Wrapper, который может получить доступ к удалённому HTTP контенту, используя стандартные функции файловой системы. Например, функция file_get_contents() может получать удалённые HTTP ресурсы так же, как и обычные файлы в файловой системе.

HTTP-обёртка заполняет локальную переменную $http_response_header после успешного установления удалённого соединения. Эта переменная заполняется в локальной области видимости и не является суперглобальной переменной.

Это исторический артефакт, использовавшийся когда-то для обеспечения доступности HTTP-заголовков, но "магическая" природа этой переменной может сбить с толку и требует специальной обработки в IDE и статических анализаторах.

file_get_contents('https://www.dev-notes.ru/');
var_dump($http_response_header);
array(15) {
[0]=> string(15) "HTTP/1.1 200 OK"
[1]=> string(30) "Alt-Svc: h3=":443"; ma=2592000"
[2]=> string(44) "Cache-Control: max-age=1800,public,immutable"
// ...
}

В PHP 8.4 добавлены две новые функции http_get_last_response_headers и http_clear_last_response_headers, которые можно использовать для получения и очистки HTTP-заголовков последнего ответа HTTP-обёртки, что может заменить историческую переменную $http_response_header.

Переменная $http_response_header не объявлена устаревшей.

Начиная с версии PHP 8.4, переменная $http_response_header не объявлена устаревшей. Однако рекомендуется использовать новые функции в приложениях, требующих PHP 8.4 или более поздней версии.

Новые функции http_(get|clear)_last_response_headers

Две новые функции, http_get_last_response_headers и http_clear_last_response_headers, предоставляют функциональность, аналогичную переменной http_response_header, но с улучшенной ясностью.

Например, вместо того чтобы заранее знать переменную $http_response_header, можно сообщить IDE и статическим анализаторам параметры и типы возвращаемых переменных. Это можно сделать с помощью заглушек функций http_get_last_response_headers и http_clear_last_response_headers.

$http_response_header не изменяется этими функциями.

Переменная $http_response_header остаётся незатронутой функциями http_(get|clear)_last_response_headers. Очистка переменной $http_response_header не влияет на функцию http_get_last_response_headers() (она продолжает возвращать значение, если оно доступно), а вызов http_clear_last_response_headers() не удаляет значение переменной $http_response_header.

Функции http_get_last_response_headers и http_clear_last_response_headers не привязаны к локальному контексту вызова. Вызов функции http_get_last_response_headers() может вернуть заголовки последнего ответа HTTP-обёртки, даже если она не была вызвана внутри области видимости. Чтобы случайно не использовать HTTP-ответы от другого запроса, обязательно вызывайте http_clear_last_response_headers().

http_get_last_response_headers

/**
* Returns HTTP response headers from the last HTTP request that
* used the HTTP wrapper. If the request failed, or if there is no
* last HTTP request, it returns null.
*
* @return array|null
**/

function http_get_last_response_headers(): ?array {}

После вызова HTTP-обёртки с успешным ответом функция http_get_last_response_headers возвращает массив заголовков HTTP-ответа. Если HTTP-ответ отсутствует или запрос не выполняется (например, из-за сбоя DNS-разрешения), возвращаемое значение будет null.

В отличие от $http_response_header, значения, возвращаемые этой функцией, не находятся в области видимости. Она может возвращать HTTP-заголовки последнего вызова HTTP-обёртки, даже если последний HTTP-запрос был сделан в другой области видимости функции.

Обратите внимание, что все HTTP-ответы, включая 404, 403 и т. д., также считаются правильными HTTP-ответами, и эта функция возвращает заголовки и для них.

http_get_last_response_headers(); // null

file_get_contents('https://www.dev-notes.ru/articles/php/8.4/http_get-clear_last_response_headers/');

http_get_last_response_headers(); // ['HTTP/1.1 200 OK', 'Cache-type: text/html', ...]

http_get_last_response_headers() возвращает заголовки (если они доступны), даже если переменная $http_response_header была изменена.

Переменная $http_response_header не определяется до первого использования HTTP-обёртки. Функция http_get_last_response_headers() в этом случае возвращает null и не выдаёт никаких ошибок/предупреждений/уведомлений.

http_clear_last_response_headers

/**
* Clears the HTTP headers from the last HTTP wrapper HTTP response.
**/

function http_clear_last_response_headers(): void {}

Вызов http_clear_last_response_headers очищает HTTP-заголовки, хранящиеся внутри, и последующие вызовы http_get_last_response_headers будут возвращать null.

Вызов этой функции не влияет на переменную $http_response_header. Однако поскольку возвращаемое значение http_get_last_response_headers не является скопированным, http_clear_last_response_headers() также очищает это значение глобально.

Замена переменной $http_response_header

Переменная $http_response_header — это исторически сложившееся поведение, которое заключается в том, что она магически неявно создаётся в текущей области видимости. Рассмотрите возможность замены переменной на вызов функции http_(get|clear)_last_response_headers, так как это обеспечивает более предсказуемый и интуитивно понятный поток кода.

В PHP 8.4 переменная $http_response_header не устарела. Однако рекомендуется использовать новые функции, где это возможно.

Кросс-версионная совместимость:

 file_get_contents('https://www.dev-notes.ru/articles/php/8.4/http_get-clear_last_response_headers/');

-$headers = $http_response_header;
+if (\PHP_VERSION_ID >= 80400) {
+ $headers = http_get_last_response_headers();
+ http_clear_last_response_headers();
+}
+else {
+ $headers = $http_response_header;
+}

Только PHP >=8.4:

 file_get_contents('https://www.dev-notes.ru/articles/php/8.4/http_get-clear_last_response_headers/');

-$headers = $http_response_header;
+$headers = http_get_last_response_headers();
+http_clear_last_response_headers();

Влияние на обратную совместимость

Полифилл этой функции в старых версиях PHP невозможен, поскольку переменная $http_response_header доступна только локально, а функции http_(get|clear)_last_response_headers не возвращают/очищают переменные с областью видимости.


Дополнительные материалы

Предыдущая Статья

PHP 8.4: Обновление PCRE2 и изменения в регулярных выражениях

Следующая Статья

Проверка типов данных в Коллекциях Laravel с помощью метода ensure()