header()报错是因为php已向浏览器输出内容(如空格、bom、echo等),导致http头被锁定;必须在所有输出前调用,常见原因包括bom、多余空白、提前输出及错误信息显示。

为什么 header() 会报“Cannot modify header information”
因为 PHP 已经向浏览器输出了任何内容(哪怕一个空格、BOM 字符或 echo),就锁死了 HTTP 头的修改权限。这个错误不是配置问题,而是执行顺序问题——header() 必须在所有输出之前调用。
常见触发点:
- 文件开头有 UTF-8 BOM(尤其 Windows 编辑器保存时默认加)
-
echo、print、var_dump()等提前执行 - 包含的文件(如
require 'config.php';)末尾有多余换行或空格 - 开启
output_buffering但缓冲未启用或已被清空
检查并清除所有隐式输出
别只盯着主脚本,整个请求链路上任何 PHP 文件末尾的空白、注释后的换行、甚至 ?> 后的空格都可能惹祸。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 用十六进制编辑器或 VS Code 的“显示不可见字符”功能查 BOM(
EF BB BF),保存为“UTF-8 无 BOM” - 所有
.php文件统一不写结束标签?>(PHP 官方推荐,彻底规避末尾空白) - 用
headers_sent($file, $line)定位哪行/哪个文件先输出:if (headers_sent($file, $line)) { die("Headers already sent in $file on line $line"); }
用 ob_start() 缓冲输出(慎用)
开启输出缓冲后,PHP 会先把内容暂存内存,等脚本结束再统一发给浏览器,这样 header() 就有了“补救窗口”。但它不是万能解药,只是兜底手段。
注意点:
- 必须在任何输出前调用,通常放在入口文件第一行(如
index.php开头) - 缓冲会增加内存占用,大文件下载或长循环中要手动
ob_flush()或ob_end_flush() - 某些环境(如 CLI、部分 SAPI)不支持缓冲,
ob_start()可能静默失败 - 别嵌套多层缓冲(
ob_start()套ob_start()),容易漏掉ob_end_flush()导致空白页
重定向前确保没触发错误或警告
PHP 错误(如 Notice: Undefined variable)即使 error_reporting 关闭,只要 display_errors = On,也会变成真实输出,直接破坏头信息。
排查方式:
- 临时把
display_errors = Off加到php.ini或用ini_set('display_errors', '0'); - 用
error_log()把错误记到文件,避免干扰输出流 - 重定向前加
exit;或die();,防止后续代码意外输出 - 如果用了框架(如 Laravel),确认中间件或视图里没有
dd()、dump()残留
?> 后的回车。这类问题不会报错,但会让 header() 彻底失效。











