PHP 8.4: 新增 http_(get|clear)_last_response_headers 函数
PHP 提供了一个 HTTP 包装器,可以使用标准文件系统函数访问远程 HTTP 内容。例如,file_get_contents()
函数可以获取远程 HTTP 资源以及文件系统上的常规文件。
在成功建立远程连接后,HTTP 包装器填充一个名为 $http_response_header
的本地变量。此变量是在局部作用域中填充的,它不是超全局变量。
这是一个历史组件,曾经用于使 HTTP 头可用,但这个变量的“魔力”性质可能会令人困惑,需要在 IDE 和静态分析器中进行特殊处理。
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 添加了两个新函数 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
变量相似的功能,但清晰度有所提高。
例如,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_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 头。
请注意,包括 404
、403
等在内的所有 HTTP 响应也被视为有效的 HTTP 响应,此函数还返回它们的响应头。
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_response_header
变量被修改,http_get_last_response_headers()
也返回响应头(如果可用).
在第一次使用 http 包装器之前,
$http_response_header
变量不会被定义。在这种情况下,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://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();
向后兼容性影响
不可能在旧版 PHP 中 polyfill 该函数,因为 $http_response_header
只在本地作用域可用,而 http_(get|clear)_last_response_headers
并不返回/清理作用域变量。