3
社区成员




PHP 的 header()
函数用于向客户端发送原始 HTTP 头信息,是实现页面重定向、设置缓存策略、控制内容类型等功能的核心工具。然而,由于其执行机制与 HTTP 协议强相关,开发者在使用时极易踩入陷阱。本文将深入分析 header()
的常见错误场景,并提供对应的解决方案与最佳实践。
echo "Hello World";
header("Location: login.php"); // 报错:Cannot modify header information...
HTTP 协议规定,响应头(Header)必须在响应体(Body)之前发送。当 PHP 脚本在调用 header()
前已输出内容(包括空格、HTML 标签、echo
/print
语句等),服务器会优先发送响应体,此时再修改头部信息会触发 Warning
级错误。
方案 1:启用输出缓冲(Output Buffering)
在脚本开头使用 ob_start()
捕获输出内容,延迟发送响应体:
ob_start();
echo "Hello World";
header("Location: login.php");
ob_end_flush(); // 输出缓冲内容
方案 2:严格分离逻辑与输出
将 header()
调用置于所有输出语句之前:
// 正确示例
header("Content-Type: application/json");
echo json_encode(['status' => 'success']);
header("Location login.php"); // 缺少冒号
header("Cache-Control: no-cache", true, 500); // 第三个参数无效
错误 1:格式不符合 HTTP 规范
Header 字段必须为 Key: Value
格式,且键名大小写不敏感(建议使用首字母大写格式,如 Content-Type
)。
修复:添加冒号分隔符:
header("Location: login.php");
错误 2:错误使用参数
header()
的第三个参数 $http_response_code
仅在设置 HTTP 状态码时生效(如 header("HTTP/1.1 404 Not Found")
),不可滥用。
修复:移除无效参数或改用 http_response_code()
:
header("HTTP/1.1 404 Not Found");
// 或
http_response_code(500);
header("Content-Type: text/html");
header("Content-Type: application/json"); // 覆盖前一条
强制替换:通过第二个参数 $replace
控制是否覆盖同名 Header(默认为 true
):
header("X-Custom-Header: Foo", false); // 允许多个同名 Header
header("X-Custom-Header: Bar", false);
避免冗余:统一管理 Header 设置逻辑,例如通过类封装:
class HeaderManager {
private static $headers = [];
public static function set($header, $replace = true) {
if (!isset(self::$headers[$header])) {
header($header, $replace);
self::$headers[$header] = true;
}
}
}
header()
声明的编码与实际文件编码不一致。
header("Content-Type: text/html; charset=UTF-8");
// 文件保存为 UTF-8 无 BOM 格式
header("Location: /login.php"); // 未使用绝对 URL
header("Location: http://example.com/login.php");
// 或
header("Location: login.php"); // 当前域下有效
header("Cache-Control: no-cache")
无效,页面仍被缓存。add_header
指令(Nginx)。session.cache_limiter
配置(默认可能发送缓存头)。headers_list()
函数输出所有已发送的 Header 进行验证。关键点 | 推荐做法 |
---|---|
输出顺序控制 | 所有 header() 调用置于脚本最顶部,避免提前输出内容。 |
路径与编码规范 | 使用绝对 URL 跳转,明确声明字符集并与文件编码一致。 |
错误处理 | 结合 headers_sent() 检查 Header 是否可发送,动态处理异常:if (!headers_sent()) { header(...); } |
代码终止 | 执行 Location 跳转后立即调用 exit 或 die ,防止后续代码意外执行。 |
通过遵循 HTTP 协议规范、合理利用输出缓冲机制,并严格管理 Header 设置逻辑,开发者可高效避免 header()
函数引发的各类问题,确保 Web 应用的稳定性和安全性。