Take the State of PHP 2026 Survey →

Add http_(get|clear)_last_response_headers() function View as Markdown

Implemented (PHP 8.4)
Authors
Gina Peter Banyard girgias@php.net
Date
2024-01-03
Version
0.2
Target
PHP 8.4
Implementation
https://github.com/php/php-src/pull/12500
Source
wiki.php.net/rfc/http-last-response-headers

Vote

Accept Add http_(get|clear)_last_response_headers() function RFC? closed
Yes
15
No
1
16 voters
alcaeus Yes 2024-01-31 07:38
alec No 2024-01-31 07:03
ashnazg Yes 2024-02-05 17:42
derick Yes 2024-01-31 10:41
devnexen Yes 2024-01-30 09:18
dharman Yes 2024-01-30 21:07
ericmann Yes 2024-01-30 23:18
galvao Yes 2024-02-14 11:50
girgias Yes 2024-01-29 11:55
ilutov Yes 2024-02-13 11:46
kocsismate Yes 2024-01-30 20:59
nielsdos Yes 2024-01-31 11:27
petk Yes 2024-01-31 20:25
sergey Yes 2024-01-31 08:35
theodorejb Yes 2024-01-31 00:40
zimt Yes 2024-02-07 09:26

Discussions on the mailing list

[RFC] Add http_(get|clear)_last_request_headers() function
by Gina P. Banyard · 10 messages
[RFC] [VOTE] Add http_(get|clear)_last_response_headers() function RFC
by Gina P. Banyard · 5 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:50 UTC

Introduction

The $http_response_headervariable is magically created in the local scope whenever an HTTP request is performed through PHP's stream layer, i.e. when using the HTTP wrapper. One such usage is using file_get_contents() to retrieve the content of a URL.

The $http_response_headervariable will contain all the HTTP headers that were encountered during the request performed via the HTTP wrapper.

All other features using this operating principle, such as $php_errormsg, have been removed because creating a variable in the local scope is a terrible way of returning additional information. This variable itself was initially slated to be deprecated in PHP 8.1, but due to a lack of convenient alternatives, it was removed from the proposal at that time.

This variable is created and populated even if the HTTP request fails, a behaviour that requires dropping down to the stream layer, providing an additional stream context to ignore errors. Subsequently, the user can manually parse the response header and detect if the HTTP request failed or not. This is impractical and a better interface would be simply checking if the return value of the initial call was false.

As a replacement, we propose adding functions similar to error_get_last()/error_clear_last() which replaced $php_errormsg.

Motivation

The primary motivation for adding this function, is to be able to remove the $http_response_headervariable completely. To create this variable one needs to use the zend_set_local_var_str() engine function. This is also the last usage of this engine function and its sibling function zend_set_local_var().

Moreover, this variable needs to be special cased in the optimizer/JIT (via the HTTP_RESPONSE_HEADER_ALIAS enum case of zend_ssa_alias_kind). Which means that any extension that would use this engine API would misbehave under opcache.

See the Backward Incompatible Changessection for an impact analysis of the removal of this feature.

Proposal

Add the following two functions:

  • function http_get_last_response_header(): ?array
  • function http_clear_last_response_header(): void

http_get_last_response_header() would provide the same information as $http_response_headerif a request via the HTTP wrapper is made, and also return the headers as an array even when the request fails. If no request via the HTTP wrapper is made, or the last headers have been cleared by calling http_clear_last_response_header(), then null is returned.

Backward Incompatible Changes

As this RFC does not yet propose deprecating $http_response_headerthere are no backward incompatible changes.

Considering the possible simplification to the engine and the optimizer by removing this last usage of the capability to create a variable in this way, we have conducted a usage analysis of the feature. We found only 65 usages in 30 projects across a sample of over 900 projects (composer packages, standalone open source projects, and private codebases) which were analyzed with Exakat. [1] Most of those usages stem from packages like Guzzle or OAuth client libraries.

It is impossible to polyfill this feature, however it is possible to write cross version compatible code in the following way:

$content = file_get_contents('http://example.com/');
if (function_exists('http_get_last_response_headers')) {
    $http_response_header = http_get_last_response_headers();
}
// Use $http_response_header as before

Considering the sparse usage of this feature, the possibility to write cross version compatible code, and the possible engine and optimizer simplifications, it seems reasonable to slate this feature for removal even without a deprecation notice if the need arises.

Rejected ideas

One suggested idea was to provide those headers via a by-reference entry to the stream context. This idea was rejected by us, and other members of the PHP Foundation, as we wish to maintain stream contexts as a stateless configuration data structure passed to the stream.

This one-to-one feature replacement does not prevent the introduction of a more generic solution for other stream wrappers. And this pair of new functions can always be slated for future deprecation and removal.

Version

Next minor version, PHP 8.4.

Vote

As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted.

Voting started on 2024-01-29 and will end on 2024-02-14.

Vote: Accept Add http_(get|clear)_last_response_headers() function RFC? — Yes: 15 · No: 1 (closed)

References

[1] https://gist.github.com/exakat/454e503458e231dc0695837ad2561540