HOWTO · PHP
在 PHP 中获取标头
本教程介绍如何使用 PHP 获取 URL 返回的 HTTP 响应头,以及 PHP 服务器收到的 HTTP 请求头。
本页内容
HTTP 标头在 HTTP 客户端与服务器之间传递元数据。选择 PHP 方法前,先确定要检查通信的哪一端:get_headers()读取对 URL 请求的响应,而 $_SERVER和请求标头函数则提供当前服务器收到的信息。
根据要检查的标头选择 PHP 方法
如果 PHP 代码需要检查某个 URL 返回的响应,请使用 get_headers()。若要检查应用处理的传入请求,可以从 $_SERVER读取指定值,或使用 apache_request_headers()或 getallheaders()获取一组标头。如果这些函数不可用或不适合,也可以筛选 $_SERVER来建立标头清单。
这些来源描述通信过程的不同部分。Content-Type之类的响应标头描述响应;User-Agent之类的请求标头则来自客户端。应用能够获取哪些值,可能取决于请求内容和服务器配置。
使用 get_headers() 获取 URL 的响应标头
get_headers()会向指定 URL 发出请求,并以数组形式返回响应标头。数组的第一项通常包含 HTTP 状态行,后面是各个标头行。返回值会受 URL、重定向、服务器响应和网络状况影响,因此不要依赖固定的线上网站标头清单。
本节中的代码以及显示的标签或输出仍为英文。
<?php
$url = 'https://example.com/';
$headers = @get_headers($url);
if ($headers === false) {
echo "No response headers were returned.\n";
} else {
foreach ($headers as $header) {
echo $header, "\n";
}
}
此示例需要可访问的 URL 和 PHP 的 URL 流支持;响应取决于执行环境,因此不展示固定输出。代码中的提示文字和输出标签保留英文。若 URL 可能来自用户,请先验证或限制 URL,并妥善处理请求失败的情况,不要假设结果一定是数组。
从 $_SERVER 读取单个请求标头
PHP 通常会将传入请求标头作为 HTTP_* 条目放在 $_SERVER中。例如,用户代理值可能位于 HTTP_USER_AGENT。此数组也包含其他服务器和请求信息,而且特定标头对应的键可能不存在。读取可选值时应使用备用值:
示例代码中的提示文字和输出标签保留英文。
本节中的代码以及显示的标签或输出仍为英文。
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null;
请将该值视为随请求传入的输入。将它用于判断或输出前应先验证;若要在页面中呈现,也应进行转义。
使用 apache_request_headers() 或 getallheaders() 获取所有请求标头
如果运行环境提供 apache_request_headers(),它会将传入请求标头作为关联数组返回。getallheaders()也有相同的基本用途。两者能否使用取决于 PHP 和服务器环境;如果代码需要在不同配置下运行,请先检查函数是否可用,再进行调用。
示例代码中的提示文字和输出标签保留英文;其中列出的标头名称和值会随请求和服务器环境而变化。
本节中的代码以及显示的标签或输出仍为英文。
<?php
if (function_exists('getallheaders')) {
$headers = getallheaders();
} elseif (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
} else {
$headers = [];
}
foreach ($headers as $name => $value) {
echo $name, ': ', $value, "\n";
}
请在提供其中一个函数的环境所处理的网页请求中运行此代码。在命令行进程中,可能没有传入的 HTTP 请求或适用的服务器 API,因此清单可能为空。
使用 $_SERVER 建立请求标头清单
如果需要备用清单,可以筛选 $_SERVER,找出键名以 HTTP_ 开头的条目,再移除该前缀并将下划线转换为连字符。此筛选只会选出这些条目,并不会包含所有服务器变量。某些请求数据(例如内容长度或内容类型)可能存放在 $_SERVER的其他键中,而不是以 HTTP_ 为前缀的键。
示例代码中的提示文字和输出标签保留英文;列出的值会因传入请求和服务器环境而异。
本节中的代码以及显示的标签或输出仍为英文。
<?php
function requestHeadersFromServer(array $server): array
{
$headers = [];
foreach ($server as $key => $value) {
if (strncmp($key, 'HTTP_', 5) !== 0) {
continue;
}
$name = str_replace('_', '-', strtolower(substr($key, 5)));
$headers[$name] = $value;
}
return $headers;
}
$headers = requestHeadersFromServer($_SERVER);
foreach ($headers as $name => $value) {
echo $name, ': ', $value, "\n";
}
这种转换会生成 user-agent这类易读名称,但无法还原服务器省略或存放在其他键下的标头。HTTP 标头名称不区分大小写,因此应用比较名称时不应依赖特定的大小写形式。显示的值会随传入请求和服务器环境而变化。