ThinkPHP6 Session必须启用SessionInit中间件、正确配置config/session.php参数且禁用原生$_SESSION和session_start(),否则Session::get()返回null而不报错。

ThinkPHP 的 Session 不是配完就能用,中间件没启、配置写错、混用原生函数,三者任一出问题,Session::get() 就返回 null,而且不报错——你得自己排查。
必须启用 SessionInit 中间件
TP6 默认不自动初始化 Session,哪怕 config/session.php 全配对了,没注册中间件就等于没通电。
- 检查
app/middleware.php是否包含thinkmiddlewareSessionInit::class - 多应用项目(比如
app/admin)要确认该中间件在对应应用的中间件栈里生效 - 禁用后
Session::get('xxx')永远是null,但不会抛异常,容易误判为“数据丢了” - CLI 环境(命令行任务、队列、定时器)天然不走 HTTP 请求链,
SessionInit不触发,别在这些地方依赖Session::get()
config/session.php 的关键参数陷阱
这个文件里写的不是“建议值”,而是直接决定 session 文件名、过期逻辑、Cookie 行为的实际开关。
-
type:设为'file'时,path必须可写(如runtime/session),否则首次写入静默失败 -
prefix:默认'think_',多个 TP 应用共用同一域名时,必须改不同前缀,否则 A 应用调clear()会清掉 B 应用的 session -
expire单位是**分钟**(不是秒),设1440= 24 小时;但实际失效还受 PHP 的session.gc_maxlifetime限制,后者若更小,以它为准 -
name改动后,浏览器 Cookie 名就变,老用户会“登录态丢失”,上线前必须评估兼容性
Redis 存储必须显式配全参数且验证扩展
Redis 是最常选的替代存储,但 ThinkPHP 会静默降级回 file,根本不会报错——你以为连上了,其实还在写本地文件。
立即学习“PHP免费学习笔记(深入)”;
- 执行
php -m | grep redis,输出必须含redis;若显示predis则不兼容,需装phpredis -
session.php中'redis' => ['host' => '127.0.0.1', 'port' => 6379, 'password' => null, 'database' => 2]——password必须显式写成null或空字符串,不可省略 - 数据库编号建议固定为
2,避免和业务 Redis 数据混用,防止FLUSHDB误清 session - 验证是否生效:控制器中调
session()->getHandler(),返回实例应为thinksessiondriverRedis
绝对不要混用原生 $_SESSION 和 session_start()
TP6 明确接管底层 handler,混用会导致状态错乱、缓存 limiter 报错、甚至 session ID 被覆盖。
- 看到
Cannot send session cache limiter?基本是某处提前调了session_start(),而SessionInit又尝试再启一次 -
$_SESSION在 TP6 里读不到值,也不建议写,框架不保证其一致性 - 所有操作必须走
thinkfacadeSession,比如Session::set('user.id', 1001)合法,但Session::get('user.id')不合法,只能先get('user')再取键 -
Session::pull('flash')是一次性读+删,适合表单提交后的提示;重复调第二次返回null
最易被忽略的是中间件缺失和 Redis 扩展类型不匹配——两者都不报错,只默默退化,问题会拖到压测或上线才爆发。
文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/xinjizixun/24861.html