session_start()报“headers already sent”错误,是因为其需在http响应头中设置set-cookie,而前置输出(空格、换行、bom、echo等)已触发头发送;bom常隐藏于utf-8文件开头或被包含文件中,可用vs code转无bom编码或xxd命令检测;ob_start()可临时缓冲输出,但根治需清除bom与冗余输出,并确保session.save_path目录权限正确且专属。

为什么 session_start() 会报 “headers already sent”
因为 HTTP 响应头必须在任何实际内容输出前发送,而 session_start() 需要设置 Set-Cookie 头;一旦脚本里有空格、换行、BOM、echo、print 或甚至错误提示(比如 Notice)提前刷出内容,头就发出去了,再调用 session_start() 就会失败。
检查并清除 BOM 和隐藏输出
UTF-8 编码的 PHP 文件如果带 BOM(字节序标记),会在文件开头悄悄插入不可见字符(如 锘?),导致“output started at”指向第一行却找不到原因。
- 用 VS Code 打开文件 → 右下角点击编码格式(如“UTF-8 with BOM”)→ 选“Save with Encoding” → 改为
UTF-8(无 BOM) - 用命令行快速检测:
head -c 3 yourfile.php | xxd,若输出含ef bb bf就是 BOM - 检查
include或require的文件——BOM 可能藏在被引入的配置文件或类文件里(比如报错提示中的/runtime/classmap.php:56) - 确认文件末尾没多余空行或空格,尤其是
?>后面跟了换行(建议直接删掉?>结束符)
用 ob_start() 暂缓输出(临时兜底方案)
这不是根治办法,但适合调试期或遗留系统快速止血。它把所有输出暂存进缓冲区,等你显式 ob_end_flush() 或脚本结束才真正发给浏览器。
- 必须放在脚本最顶部,且早于任何输出(包括空格):
ob_start(); - 之后再调用
session_start();就不会因前置输出失败 - 注意:如果启用了
output_buffering(php.ini 中设为On或数值),就不必手动加ob_start(),但得确认该配置已生效(可用ini_get('output_buffering')验证) - 别滥用——缓冲会增加内存占用,且掩盖真实问题,上线前仍应回归清理 BOM/输出逻辑
验证 session.save_path 权限和配置
即使没有输出问题,session_start() 也可能静默失败(比如返回 false 却不报错),表现为登录后状态不保持——这时大概率是会话写入失败。
- 查当前路径:
var_dump(ini_get('session.save_path'));,常见值如/var/lib/php/sessions或/tmp - 确认目录存在且 Web 进程用户(如
www-data、nginx或apache)有读写权限:ls -ld /var/lib/php/sessions - 若权限不足,修复命令示例:
sudo chown www-data:www-data /var/lib/php/sessions && sudo chmod 733 /var/lib/php/sessions - 避免用
/tmp在多租户环境——不同站点可能互相干扰,建议为项目单独配session.save_path
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











