PHP如何获取Apache服务器当前页面的所有响应头?
PHP获取当前页面Apache全量响应头实现方案
不要使用get_headers()请求本地地址的方案,该方案会发起新的HTTP请求,触发循环等待死锁:当前脚本运行时占用Web服务工作进程,新发起的本地请求需要等当前脚本执行完才能被处理,而当前脚本又在等待新请求的响应返回,最终会超时崩溃。
直接使用PHP原生提供的headers_list()函数即可实现需求:该函数会直接读取当前请求上下文下,PHP已准备发送给客户端的所有响应头,全程在本地进程内完成,不需要发起任何网络请求,完全不会有死锁问题。
实现注意事项
headers_list()返回的是响应头键值对数组,不包含首行的HTTP状态行,需要结合$_SERVER['SERVER_PROTOCOL'](获取HTTP协议版本)、http_response_code()(获取响应状态码)自行拼接状态行- 收集响应头的逻辑建议放在所有
header()调用、Cookie设置操作之后,正式输出页面内容之前,才能拿到最终发送给浏览器的完整响应头 - 该方法可以拿到Apache默认追加的所有响应头,包括
Server、X-Powered-By、Content-Type、Connection等字段,和浏览器实际收到的响应头完全一致
可直接运行的代码示例
代码逻辑和原有获取请求头的结构完全兼容:
<?php $DataFromBrowser = ''; $DataToBrowser = ''; // 原有获取浏览器请求头的逻辑 $headers = getallheaders(); foreach($headers as $key=>$val){ $DataFromBrowser .= $key . ': ' . $val . "\n"; } // 新增获取当前Apache响应头的逻辑 $responseHeaders = ''; // 拼接HTTP状态行 $protocol = $_SERVER['SERVER_PROTOCOL']; $statusCode = http_response_code(); // 常见状态码对应原因短语,覆盖绝大多数日常场景 $reasonPhrases = [ 200 => 'OK', 301 => 'Moved Permanently', 302 => 'Found', 304 => 'Not Modified', 400 => 'Bad Request', 403 => 'Forbidden', 404 => 'Not Found', 500 => 'Internal Server Error', 502 => 'Bad Gateway', 503 => 'Service Unavailable' ]; $reason = $reasonPhrases[$statusCode] ?? ''; $responseHeaders .= "$protocol $statusCode $reason\n"; // 拼接所有响应头字段 foreach(headers_list() as $header) { $responseHeaders .= $header . "\n"; } // 输出结果 echo "Data from browser"; echo '<textarea rows="12" style="width:100%;">' . $DataFromBrowser . '</textarea>'; echo "<br>Data to browser (Apache response headers)"; echo '<textarea rows="12" style="width:100%;">' . $responseHeaders . '</textarea>'; ?>
运行后输出的响应头格式和预期完全一致:
HTTP/1.1 200 OK
Date: Wed, 08 Jun 2022 16:53:45 GMT
Server: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/8.0.3
X-Powered-By: PHP/8.0.3
Content-Length: 589
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
内容的提问来源于stack exchange,提问作者Martin Viljoen
相关产品推荐
相关产品推荐

