apache_response_headers() 函数用于获取 Apache 服务器的所有 HTTP 响应头信息。响应头是服务器发送给客户端的 HTTP 头部信息,包含了关于响应的元数据。
header() 函数设置的响应头,以及 Apache 自动添加的一些响应头。
apache_response_headers() 和 apache_request_headers() 是不同的函数。前者获取服务器发送的响应头,后者获取客户端发送的请求头。
apache_response_headers ( ) : array|false
该函数没有参数。
函数返回一个包含所有 HTTP 响应头的关联数组,失败则返回 FALSE。
返回的数组格式如下:
典型的响应头可能包括:
Content-Type - 响应内容的类型Content-Length - 响应内容的长度Cache-Control - 缓存控制指令Server - 服务器信息Date - 响应生成的日期和时间Expires - 响应过期时间下面的示例演示如何使用 apache_response_headers() 函数获取所有 HTTP 响应头并打印出来。
<?php
// 设置一些响应头
header('Content-Type: text/html; charset=utf-8');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('X-Powered-By: PHP/8.0');
// 获取所有 HTTP 响应头
$responseHeaders = apache_response_headers();
// 检查是否成功获取
if ($responseHeaders !== false) {
echo "<h3>HTTP 响应头信息:</h3>";
echo "<table class='table table-bordered'>";
echo "<thead><tr><th>响应头名称</th><th>值</th></tr></thead>";
echo "<tbody>";
// 遍历并打印所有响应头
foreach ($responseHeaders as $header => $value) {
echo "<tr><td><strong>$header</strong></td><td>$value</td></tr>";
}
echo "</tbody></table>";
// 显示响应头总数
echo "<p>总共 " . count($responseHeaders) . " 个响应头</p>";
} else {
echo "无法获取 HTTP 响应头信息。请确保在 Apache 服务器环境下运行。";
}
?>
运行结果示例:
| 响应头名称 | 值 |
|---|---|
| Content-Type | text/html; charset=utf-8 |
| Cache-Control | no-cache, must-revalidate |
| Expires | Mon, 26 Jul 1997 05:00:00 GMT |
| X-Powered-By | PHP/8.0 |
| Server | Apache/2.4.41 |
| Date | Mon, 14 Jun 2023 10:30:00 GMT |
总共 6 个响应头
下面的示例演示如何检查特定的 HTTP 响应头,如 "Content-Type" 或缓存相关的响应头。
<?php
// 根据条件设置不同的响应头
$isApiRequest = isset($_GET['api']);
if ($isApiRequest) {
// API 请求 - 设置 JSON 响应
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('X-API-Version: 1.0');
} else {
// 普通 HTML 请求
header('Content-Type: text/html; charset=utf-8');
header('X-Frame-Options: DENY');
}
// 设置缓存控制
$noCache = isset($_GET['nocache']);
if ($noCache) {
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
} else {
header('Cache-Control: public, max-age=3600');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
}
// 获取响应头
$responseHeaders = apache_response_headers();
if ($responseHeaders !== false) {
echo "<h3>当前响应头配置:</h3>";
// 检查内容类型
if (isset($responseHeaders['Content-Type'])) {
$contentType = $responseHeaders['Content-Type'];
echo "内容类型: <code>$contentType</code><br>";
if (strpos($contentType, 'application/json') !== false) {
echo "当前为 API 响应模式<br>";
} elseif (strpos($contentType, 'text/html') !== false) {
echo "当前为 HTML 响应模式<br>";
}
}
// 检查缓存控制
if (isset($responseHeaders['Cache-Control'])) {
$cacheControl = $responseHeaders['Cache-Control'];
echo "缓存控制: <code>$cacheControl</code><br>";
if (strpos($cacheControl, 'no-cache') !== false || strpos($cacheControl, 'no-store') !== false) {
echo "缓存已被禁用<br>";
} else {
echo "缓存已启用<br>";
}
}
// 检查自定义响应头
$customHeaders = array_filter($responseHeaders, function($key) {
return strpos($key, 'X-') === 0;
}, ARRAY_FILTER_USE_KEY);
if (!empty($customHeaders)) {
echo "<h4>自定义响应头:</h4>";
foreach ($customHeaders as $header => $value) {
echo "<strong>$header</strong>: $value<br>";
}
}
} else {
echo "无法获取响应头信息";
}
?>
下面的示例演示如何使用 apache_response_headers() 来调试和验证响应头是否正确设置。
<?php
// 响应头调试函数
function debugResponseHeaders() {
$headers = apache_response_headers();
if ($headers === false) {
return "无法获取响应头信息(可能不在Apache环境下)";
}
$output = "<div style='background:#f8f9fa;padding:10px;border:1px solid #ddd;'>";
$output .= "<h4 style='margin-top:0;'>响应头调试信息</h4>";
$output .= "<ul style='margin-bottom:0;'>";
foreach ($headers as $name => $value) {
$output .= "<li><strong>$name</strong>: $value</li>";
}
$output .= "</ul></div>";
return $output;
}
// 验证响应头设置
function validateResponseHeaders($expectedHeaders) {
$actualHeaders = apache_response_headers();
if ($actualHeaders === false) {
return "无法验证响应头:无法获取当前响应头";
}
$issues = [];
$actualHeadersLower = array_change_key_case($actualHeaders, CASE_LOWER);
foreach ($expectedHeaders as $expectedName => $expectedValue) {
$expectedNameLower = strtolower($expectedName);
if (!isset($actualHeadersLower[$expectedNameLower])) {
$issues[] = "缺少响应头: $expectedName";
} elseif ($actualHeadersLower[$expectedNameLower] !== $expectedValue) {
$issues[] = "响应头 '$expectedName' 值不匹配。期望: '$expectedValue', 实际: '{$actualHeadersLower[$expectedNameLower]}'";
}
}
return empty($issues) ? "所有响应头验证通过" : implode("<br>", $issues);
}
// 设置一些响应头
header('Content-Type: text/html; charset=utf-8');
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: DENY');
// 输出调试信息
echo debugResponseHeaders();
echo "<hr>";
// 验证响应头
$expected = [
'Content-Type' => 'text/html; charset=utf-8',
'X-Content-Type-Options' => 'nosniff',
'X-Frame-Options' => 'DENY'
];
echo "<h4>响应头验证结果:</h4>";
echo validateResponseHeaders($expected);
?>
apache_response_headers() 和 headers_list() 都可以获取响应头,但有一些区别:
apache_response_headers() - 获取Apache处理后的所有响应头(包括Apache自动添加的)headers_list() - 获取PHP脚本通过header()函数设置的所有响应头<?php
// 设置一些响应头
header('Content-Type: text/html; charset=utf-8');
header('X-Custom-Header: MyValue');
header('Cache-Control: no-cache');
// 获取两种方式的结果
$apacheHeaders = apache_response_headers();
$phpHeaders = headers_list();
echo "<div class='row'>";
echo "<div class='col-md-6'>";
echo "<h4>apache_response_headers() 结果:</h4>";
if ($apacheHeaders !== false) {
echo "<ul>";
foreach ($apacheHeaders as $name => $value) {
echo "<li><strong>$name</strong>: $value</li>";
}
echo "</ul>";
echo "<p>总数: " . count($apacheHeaders) . "</p>";
} else {
echo "<p class='text-danger'>无法获取Apache响应头</p>";
}
echo "</div>";
echo "<div class='col-md-6'>";
echo "<h4>headers_list() 结果:</h4>";
echo "<ul>";
foreach ($phpHeaders as $header) {
echo "<li>$header</li>";
}
echo "</ul>";
echo "<p>总数: " . count($phpHeaders) . "</p>";
echo "</div>";
echo "</div>";
// 比较差异
echo "<h4 class='mt-4'>比较分析:</h4>";
echo "<ul>";
echo "<li><code>apache_response_headers()</code> 通常包含更多响应头,因为Apache会自动添加一些(如Server、Date等)</li>";
echo "<li><code>headers_list()</code> 只返回通过PHP的<code>header()</code>函数设置的响应头</li>";
echo "<li>如果同一个响应头被多次设置,<code>apache_response_headers()</code> 返回最后设置的值,而<code>headers_list()</code>可能包含多个值</li>";
echo "</ul>";
?>
如果你需要在非 Apache 服务器环境下获取响应头信息,可以使用以下方法:
<?php
/**
* 获取响应头信息的兼容函数
* @return array 包含响应头信息的数组
*/
function getResponseHeadersCompatible() {
// 优先使用 apache_response_headers()
if (function_exists('apache_response_headers')) {
$headers = apache_response_headers();
if ($headers !== false && !empty($headers)) {
return $headers;
}
}
// 使用 headers_list() 作为备选
$headers = [];
$headersList = headers_list();
foreach ($headersList as $header) {
// 分割响应头名称和值
if (strpos($header, ':') !== false) {
list($name, $value) = explode(':', $header, 2);
$headers[trim($name)] = trim($value);
}
}
return $headers;
}
// 使用兼容函数
$responseHeaders = getResponseHeadersCompatible();
echo "<h3>响应头信息(兼容版本):</h3>";
if (!empty($responseHeaders)) {
foreach ($responseHeaders as $header => $value) {
echo "<strong>$header</strong>: $value<br>";
}
} else {
echo "没有设置响应头或无法获取响应头信息";
}
// 另一种方法:模拟响应头(用于测试)
function simulateResponseHeaders() {
$simulated = [
'Content-Type' => 'text/html; charset=utf-8',
'X-Powered-By' => 'PHP/' . PHP_VERSION,
'Server' => 'WebServer',
'Date' => gmdate('D, d M Y H:i:s') . ' GMT'
];
// 添加实际设置的响应头
foreach (headers_list() as $header) {
if (strpos($header, ':') !== false) {
list($name, $value) = explode(':', $header, 2);
$simulated[trim($name)] = trim($value);
}
}
return $simulated;
}
?>
apache_response_headers() 函数仅在 Apache 服务器环境下有效。headers_list()只返回PHP设置的响应头,而apache_response_headers()返回所有响应头(包括Apache添加的)。