PHP 8.4: New http_(get|clear)_last_response_headers functions

Version8.4
TypeNew Feature

PHP provides an HTTP Wrapper, that can access remote HTTP content using standard file system functions. For example, the file_get_contents() function can fetch remote HTTP resources as well as regular files on the file system.

The HTTP wrapper populates a local variable named $http_response_header after a remote connection is successfully made. This variable is populated in the local scope, and it is not a super global variable.

This is a historical artifact that was once used to make the HTTP headers available, but the "magic" nature of this variable can be confusing and requires special handling in IDEs and static analyzers.

file_get_contents('https://php.watch');
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 adds two new functions named http_get_last_response_headers and http_clear_last_response_headers that can be used to get and clear the HTTP headers of the last HTTP wrapper response, which can replace the historical $http_response_header variable.

$http_response_header variable is not deprecated
As of PHP 8.4, the $http_response_header variable is not deprecated. However, it is recommended to use the new functions on applications that require PHP 8.4 or later.

New http_(get|clear)_last_response_headers functions

The two new functions, http_get_last_response_headers and http_clear_last_response_headers provide similar functionality as the http_response_header variable, but with improved clarity.

For example, instead of having prior knowledge of the $http_response_header variable, IDEs and static analyzers can be made aware of the parameter and return types of the variables using http_get_last_response_headers and http_clear_last_response_headers functions stubs.

$http_response_header is not modified by these functions
The $http_response_header variable remains untouched by the http_(get|clear)_last_response_headers functions. Clearing the $http_response_header variable has no impact on the http_get_last_response_headers() function (it continues to return the value if available), and calling http_clear_last_response_headers() does not unset the $http_response_header variable.

http_get_last_response_headers and http_clear_last_response_headers functions are not scoped to the local calling context. Calling http_get_last_response_headers() can return the headers of the last HTTP wrapper response even if it's not called inside the scope. To prevent accidentally using HTTP responses from another request, make sure to call 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 {}

After an HTTP wrapper call with a successful response, the http_get_last_response_headers function returns an array of HTTP response headers. If there is no HTTP response, or if the request fails (e.g. due to a DNS resolving failure), the return value will be null.

Unlike the $http_response_header, the values returned by this function are not within the scope. It can return HTTP headers of the last HTTP wrapper call even if the last HTTP request was made in another function call scope.

Note that all HTTP responses including 404, 403, etc are also considered valid HTTP responses, and this function returns the headers for them as well.

http_get_last_response_headers(); // null

file_get_contents('https://php.watch/versions/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() returns the headers (if available) even if the $http_response_header variable was modified.

The $http_response_header variable is not defined until the first time the HTTP wrapper is used. http_get_last_response_headers() function returns null in this case, and emits no errors/warnings/notices.

http_clear_last_response_headers

/**  
 * Clears the HTTP headers from the last HTTP wrapper HTTP response.
 **/
function http_clear_last_response_headers(): void {}

Calling http_clear_last_response_headers clears the HTTP headers stored internally, and subsequent http_get_last_response_headers will return null.

Calling this function has no impact on the $http_response_header variable. However, since the http_get_last_response_headers return value is not scoped, http_clear_last_response_headers() also clears the value globally.

Replacing $http_response_header variable

The $http_response_header variable is a historical behavior that it is a magicallyimplicitly created variable within the current scope. Consider replacing the variable with http_(get|clear)_last_response_headers function calls as it provides a more predictable and intuitive code flow.

PHP 8.4 does not deprecate the $http_response_header variable. However, it is recommended to use the new functions where possible.


Cross-version compatible:

  file_get_contents('https://php.watch/versions/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 only

  file_get_contents('https://php.watch/versions/8.4/http_get-clear_last_response_headers');

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

Backward Compatibility Impact

It is not possible to polyfill this function in older PHP versions because the $http_response_header variable is only available locally, and the http_(get|clear)_last_response_headers functions do not return/clear scoped variables.


RFC Discussion Implementation