最常见原因是bom字符或提前输出破坏http头发送流程:bom(\xef\xbb\xbf)在php执行前被输出,或echo、空格、错误警告等导致headers已发送;须用grep检测并批量清除bom,同时检查所有引入文件及中间件顺序。

ThinkPHP 中 Header 报错,最常见的是 headers already sent,本质是 HTTP 响应头被提前输出,导致后续 header()、session_start() 或框架自动发送头失败。这不是 ThinkPHP 的 Bug,而是输出控制被破坏的结果。
检查是否有 BOM 字符干扰
BOM(\xEF\xBB\xBF)是 UTF-8 文件开头的三个不可见字节,常被编辑器悄悄写入。它会在任何 PHP 代码执行前被输出,直接触发 headers 已发送错误。
- 不要依赖编辑器状态栏显示“无 BOM”——实际可能仍有;用命令行检测:
grep -rl $'\xEF\xBB\xBF' app/ config/ public/ - 清除时需批量处理所有手写 PHP 文件(如
app/common.php、config/app.php),不能只改入口文件 - 推荐用 VS Code 或 Notepad++ 打开后另存为“UTF-8 无 BOM”格式,注意保存时确认编码选项真实生效
确认没有意外输出
除 BOM 外,任何提前的 echo、print、var_dump、空格、换行,甚至错误警告(如 Notice: Undefined index)都会造成输出。
- 在调用
header()前加一句:if (headers_sent($file, $line)) { die("Headers already sent in $file on line $line"); } - 检查所有被
require/include的配置文件、函数库,尤其注意末尾是否有多余空行或分号后换行 - 关闭调试模式(
app_debug => false)可隐藏 Notice/Waring,但治标不治本;应定位并修复源头
跨域中间件或手动 header 写法不当
自定义 CORS 头或使用 think\middleware\Cors 时,若位置靠后、被跳过或响应已被终止,header 就不会生效。
- 确保
think\middleware\Cors::class在app/middleware.php全局中间件数组中,且排在第 2 或第 3 位(必须早于 Session、Auth 等中间件) - 不要在控制器里用
exit(json_encode(...))或die(),这会中断中间件链,header 来不及设置 - 若设了
allowCredentials => true,则Access-Control-Allow-Origin不能为*,必须动态匹配Origin头并显式写出
Apache 下 Authorization 头丢失
前端带 Authorization: Bearer xxx,但 $request->header('authorization') 取不到——这是 Apache 默认过滤该头导致的。
- 在项目根目录
.htaccess中添加:RewriteCond %{HTTP:Authorization} .+和RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] - 或修改 Apache 虚拟主机配置:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 - Nginx 用户无需此操作,但需确认
fastcgi_pass配置中透传了Origin和Authorization头
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











