session_start()必须在任何输出前调用,需清除BOM、空格、错误提示等提前输出,并推荐用ob_start()兜底或session_status()校验会话状态。

这个问题很常见,核心就一条:session_start() 必须在任何输出产生之前调用。哪怕一个空格、换行或不可见的 BOM 字符,都会让 PHP 提前发送 HTTP 头,导致 session_start() 失败。
检查文件开头有没有 BOM 或多余空格
BOM 是 UTF-8 文件开头可能存在的三个不可见字节(EF BB BF),Windows 记事本、某些编辑器默认会加上它,PHP 会把它当作输出。表现就是报错里提示“output started at xxx.php:1”。
- 用支持编码查看的编辑器(如 VS Code、Notepad++、Sublime)打开文件,确认编码是“UTF-8 无 BOM”
- 把光标移到最开头,删掉所有看不见的字符;也可以另存为 UTF-8(无 BOM)格式
- 检查
<?php前面有没有空行、空格或注释
确保没有提前输出内容
不只是 echo/print,include 的文件、错误警告、甚至 PHP 自身的 Notice 都算输出。
- 把
session_start()放到整个脚本最顶部,第一行(不考虑空白和注释) - 检查所有被 include/require 的配置文件、函数库,确认它们没 echo、var_dump、print_r 或末尾多余的空行
- 临时关闭错误显示:
error_reporting(0);,避免警告信息意外输出
启用输出缓冲(快速兜底方案)
如果一时找不到哪行输出了,或者项目老旧难以逐个排查,可以用输出缓冲“兜住”所有提前输出。
立即学习“PHP免费学习笔记(深入)”;
- 在脚本最开头加:
ob_start(); - 再调用:
session_start(); - 最后(通常在脚本结尾)加:
ob_end_flush();或留空由 PHP 自动输出 - 更彻底的做法:在 php.ini 中设
output_buffering = On或指定数值(如 4096),全局生效
验证会话状态再启动
避免重复调用引发干扰,也防止在已启动会话时出错。
- 用
if (session_status() === PHP_SESSION_NONE) { session_start(); } - 配合
headers_sent()检查是否真有输出:if (!headers_sent()) { session_start(); } else { error_log('Headers already sent'); }



















