登录接口返回成功,跳转到后台首页,打印 $_SESSION 却是空数组。同一套代码在本地正常,放到服务器就不行,日志里一行 headers already sent 提示了方向。这类 php session 取不到值的情况,八成出在会话没开起来或者 cookie 没带上。

session_start 必须在最前面

php session 依赖 session_start() 开启,这个调用要放在任何输出之前,包括空格、BOM、echo。文件开头多一个空行,header 就发不出去,会话 ID 的 cookie 写不进浏览器,下一次请求自然拿不到数据。排查时看报错文件的行号,往前找第一个输出点。

<?php session_start(); $_SESSION['user_id'] = 12; echo $_SESSION['user_id'];

cookie 的域和路径要对得上

网站从 www 跳转到不带 www 的域名,cookie 默认不共享,会话就断了。在 php.ini 里把 session.cookie_domain 设成主域,路径保持根目录。session.cookie_lifetime 是 cookie 在浏览器里的存活时间,session.gc_maxlifetime 是服务器端文件的清理时间,默认 1440 秒,后台操作慢的话可以调大。

多台服务器要换存储方式

默认 session 以文件形式存在 session.save_path 指向的目录,多台机器各存各的,请求轮到另一台就丢登录态。一般改成 Redis 或者数据库统一存,改 php.ini 的 session.save_handler 和 save_path,或者用 session_set_save_handler 自己接管。目录权限也要看一眼,Linux 下属主不对,写入失败同样拿不到数据。

登录后记得换 ID

用户登录成功,调一次 session_regenerate_id(true),把旧会话文件删掉,能减少会话固定攻击的风险。$_SESSION 里别塞大对象,序列化后每个请求都要读写,数据多了明显拖慢。退出时先 session_unset() 再 session_destroy(),只清变量不销毁会话,换个页面又活了。