ThinkPHP 6.1+ 的 session.driver 必须显式配置为 think\session\driver\Redis,不再支持字符串 'redis';需独立设置 session.name 防跨应用污染,Redis 过期时间必须由 session.expire 统一控制,且推荐使用 Predis 或 think-redis 扩展适配 Cluster/哨兵模式。

ThinkPHP 6.1+ 的 session.driver 不再支持 redis 字符串写法
升级后直接沿用 TP5 的 'redis' 配置会静默退化为 file 驱动,Session 看似正常实则未走 Redis。根本原因是 TP6+ 的 Session 驱动注册机制变了,redis 被当作自定义驱动名而非内置驱动标识。
- 正确写法必须显式指定完整类名:
session.driver = think\session\driver\Redis - 配置项
session.redis.host、session.redis.port等仍可用,但前提是驱动类已加载 - 若使用 Swoole 或 RoadRunner,还需确认
think\session\driver\Redis类内部是否调用fsockopen—— 它在协程环境下会阻塞,应改用Predis或ext-redis的非阻塞连接方式
多应用(multi-app)下 session.name 冲突导致跨应用会话污染
默认所有应用共用 PHPSESSID,A 应用登录后,B 应用读到同一 Session ID 就可能误复用用户数据,尤其在单点登录或微前端场景中极易出问题。
- 每个应用必须独立设置
session.name,例如:app1→app1_sid,admin→admin_sid - 若共用 Redis 实例,建议按应用前缀隔离 key:
session.driver_options.prefix = app1:session: - 注意 Cookie 域名范围:
session.domain若设为.example.com,子域间仍可共享;如需完全隔离,应设为具体子域(如app1.example.com)
think\session\driver\Redis 默认不支持 Redis Cluster 和哨兵模式
原生驱动只认单节点 Redis,遇到 Moved 或 Ask 重定向错误时直接抛异常,日志里常见 ERR invalid password(其实是连接错节点了,但报错误导性极强)。
- Cluster 场景必须换驱动:推荐继承
think\session\driver\Redis,内部替换连接逻辑为Predis\Client并启用cluster => 'redis'模式 - 哨兵模式需手动构造
Sentinel实例,再通过getMaster()获取主节点地址传给 Redis 驱动 —— 不能直接填哨兵地址到host - TP6.3+ 可配合
topthink/think-redis扩展包,它提供了兼容 Cluster 的RedisCluster驱动,但需自行绑定到 Session
Session 过期时间在分布式环境下必须统一由 Redis 控制,不能依赖 PHP 的 gc_maxlifetime
多进程/多机器部署时,PHP 自带的 session GC 是本地触发、不可靠的;Redis 的 TTL 才是唯一可信的过期依据。若只改 session.gc_maxlifetime 而不同步 session.expire,会出现“用户刚登出,10 分钟后又自动登录”的诡异现象。
立即学习“PHP免费学习笔记(深入)”;
-
session.expire必须显式设为与 Redis key TTL 一致的秒数(如7200),它会作为SETEX的过期参数传入 -
session.use_strict_mode = true必开,防止攻击者伪造旧 Session ID 强行续期 - 如果业务需要动态延长有效期(如“记住我”),不要调用
session_regenerate_id(),而应直接对 Redis 中对应 key 执行EXPIRE



















