“Cannot modify header information”错误本质是HTTP头已发送,无法再修改;关键定位“谁先输出了内容”,常见原因包括调试语句残留、文件首尾空白、BOM、include文件隐式输出及nginx error_page配置不当等。

“Cannot modify header information” 错误怎么快速定位
这个报错不是 header 本身坏了,而是 PHP 已经把 HTTP 头发出去了,你再想改就晚了。关键看「谁先输出了内容」。
常见触发点包括:
-
echo、print、var_dump()等调试语句漏删 - PHP 文件开头或结尾有空格、换行(尤其
?>后多敲了一个回车) - 被
include或require的公共文件(比如config.php)末尾带 BOM 或空白 - UTF-8 编码文件含 BOM:Notepad++ 中用「编码 → 转为 UTF-8 无 BOM 格式」可解决
nginx 下 error_page 404 /404.php 里 header("Location:...") 不跳转
nginx 默认会把原始状态码(404)透传给后端,即使你在 /404.php 里写了 header("Location: /new.php"),最终响应仍是 404 + Location 头,浏览器不执行跳转。
正确写法是让 nginx 放弃强制 404 状态:
立即学习“PHP免费学习笔记(深入)”;
- 把
error_page 404 /404.php;改成error_page 404 = /404.php;(注意等号) - 或者在
location块里加fastcgi_intercept_errors off; - 确保
/404.php里调用header("Location: ..."); exit;,否则 nginx 可能仍返回 404
header("Location: ...") 写对了却没跳,还执行了后续代码
header 只是发个指令,不终止脚本。浏览器收到 302 + Location 后发起新请求,但当前 PHP 进程还在跑。
后果很实际:
- 用户看到跳转,但数据库已插入重复记录(比如注册后没 exit,又执行了一次写库)
- 页面显示混乱(header 后又 echo HTML)
- 部分代理或旧浏览器可能忽略无
exit的重定向
必须加 exit 或 die:
header("Location: /success.php");
exit;
本地能跳、线上报错,大概率是输出缓冲配置差异
开发环境常默认开启 output_buffering,掩盖了提前输出问题;生产环境关了,就立刻暴露。
别依赖环境一致性,主动控制更可靠:
- 在入口文件最开头加
ob_start();(比如index.php第一行) - 避免在框架或 Composer 自动加载逻辑里偷偷输出(某些日志类、debug 工具会在构造时 echo)
- 检查
phpinfo()输出里的output_buffering值:0 表示关闭,4096 表示启用 4KB 缓冲
真正难排查的,往往不是语法错误,而是某个被 include 的配置文件末尾多了一个看不见的空格,或者某次 Git 合并引入了带 BOM 的第三方脚本。



















