TP6中session()不再自动启动,需显式调用session()->start();cookie()默认禁用HttpOnly和Secure,生产环境必须启用;Session类重构,Redis配置键名改为'hostname'/'hostport',UA绑定已移除,需手动校验。

ThinkPHP 5.1 升级到 6.x 后 session() 不再自动启动
TP6 默认关闭了 session 的自动启动,这和 TP5.1 的行为完全不同——你调用 session('key', 'val') 时,如果没手动开启,会静默失败,$_SESSION 里啥也没有,但也不报错。
常见错误现象:session('user_id') 返回 null,但 $_SESSION 确实有数据;或者登录后刷新就掉登录态。
- 必须在中间件或控制器初始化阶段显式调用
session()->start() - 不推荐在全局配置里开
'auto_start' => true(TP6 已移除该配置项) - 如果用了多应用模式,注意 session 配置在
app/middleware.php或中间件类中生效,而非config/session.php全局加载时机
TP6 的 cookie() 默认禁用 HTTPOnly 和 Secure,但生产环境必须开
TP6 中 cookie() 函数默认参数是 ['httponly' => false, 'secure' => false],而 TP5.1 是 true。本地开发可能没问题,一上 HTTPS 环境,Cookie 就被浏览器拒收,导致登录态丢失、CSRF token 失效。
使用场景:JWT 存 cookie、登录态标识、跨域鉴权凭证。
立即学习“PHP免费学习笔记(深入)”;
- 全局统一设置:在
app/middleware.php中注册中间件,对所有响应强制设置Cookie::set($name, $val, ['httponly' => true, 'secure' => true, 'samesite' => 'Strict']) - 单独调用时务必显式传参:
cookie('token', $val, ['httponly' => true, 'secure' => request()->isSecure()]) -
samesite值不能硬写'None',否则 Chrome 80+ 会直接丢弃;非跨站场景用'Lax'更安全
TP5.1 的 Session::init() 在 TP6 中已不存在,替代方案要改写
很多老项目在 common.php 或服务提供者里写了 Session::init(['type' => 'redis']),TP6 报错:Class 'think\Session' not found。因为 Session 类已被重构为独立组件,且初始化逻辑下沉到 think\facade\Session 和容器绑定。
性能影响:直接 new 实例或跳过容器会导致 Redis 连接重复创建、配置无法复用。
- 正确方式是改用依赖注入或门面:
\think\facade\Session::store('redis'),前提是已在config/session.php中配好'type' => 'redis' - Redis 配置键名变了:TP5.1 用
'host'/'port',TP6 要用'hostname'/'hostport'(注意不是'port'),否则连接超时也不报具体错误 - 如果自定义了 SessionHandler,必须实现
SessionHandlerInterface,且read()方法返回空字符串而非null,否则 TP6 会认为 session 无效并重置
TP6 的 Session ID 不再默认绑定 User-Agent,但反爬/风控逻辑可能因此失效
TP5.1 默认开启 UA 绑定('use_uagent' => true),TP6 移除了这个开关。如果你的系统靠 UA 变化主动销毁 session 来防 token 盗用,升级后这段逻辑就白写了。
容易踩的坑:前端发请求时带了 User-Agent: okhttp/4.9.0(Android App),但后续请求变成 okhttp/4.10.0,TP5.1 会清 session,TP6 不会。
- 需要自行补全 UA 校验:在登录成功后存一份 hash 到 session,每次请求前比对
hash_hmac('sha256', $_SERVER['HTTP_USER_AGENT'], $secret) - 不要直接比对原始 UA 字符串——移动端版本号变、iOS 微信内置浏览器 UA 动态变化太频繁
- 如果用了多端(Web/App/小程序),建议把设备指纹(如
navigator.platform + screen.width拼接哈希)也纳入校验维度,但别只依赖前端传值
Session 和 Cookie 的语义没变,但 TP6 把控制权交得更彻底——它不替你做决定,但也不会提醒你漏了什么。最麻烦的不是写法改了,而是那些“本来就不该依赖框架默认行为”的地方,现在突然暴露出来。



















