frankenphp 1.4 worker 模式下必须弃用原生 session,改用 redis 手动管理:统一 sess_{id} 键名、ttl 与 gc_maxlifetime 对齐,入口首行设 cookie 参数、禁用 strict_mode 并显式指定 session_name。

FrankenPHP 1.4 在 worker 模式下,原生 PHP session 机制天然不支持多实例共享——这不是配置错误,而是设计使然。每个 worker 是独立常驻进程,调用 session_start() 会各自初始化隔离的会话环境,导致 PHPSESSID 冲突、数据覆盖、登录态跨实例丢失。必须彻底弃用内置 session,改用手动 Redis 会话管理。
禁用 session_start(),改用手动 Redis 读写
官方明确要求:worker 模式下不得调用 session_start()。所有会话逻辑需由你完全接管:
- 从
$_COOKIE['PHPSESSID']或请求头Cookie中提取会话 ID(注意前端需透传) - 用 Redis 读取
sess_{id}键,再unserialize()(老框架如 TP5.1 依赖原生 PHP 序列化格式) - 修改数据后,用
Redis::setex("sess_{$sid}", $gc_maxlifetime, serialize($data))写回 - 所有实例必须使用完全一致的 key 命名规则(如
sess_{id})、TTL(建议与session.gc_maxlifetime对齐)和 Redis 连接参数
Cookie 参数必须全局统一且提前设置
多个 worker 若 cookie 的 domain/path/secure/httpOnly 不一致,浏览器可能发送多个 PHPSESSID,后端无法对齐:
- 在每个入口脚本最开头(无任何输出前)强制调用:
session_set_cookie_params(0, '/', '.example.com', true, true);
第 4 个参数为Secure,第 5 个为HttpOnly - Nginx 反代时确认已启用:
proxy_pass_request_headers on;proxy_set_header Cookie $http_cookie;
关闭 session.use_strict_mode 防静默失效
PHP 8.4+ 默认开启 session.use_strict_mode = 1,worker 模式下易因 ID 格式校验失败而拒收请求且不报错:
- 在入口脚本最开头(早于任何 session 相关操作)加:
ini_set('session.use_strict_mode', 0); - 该设置仅关闭 ID 合法性检查,不影响安全性——实际有效性由你手动控制:Redis 里没这个 key 就是未登录
确保会话名称和生命周期参数一致
避免因命名或超时差异引发隐性不一致:
- 显式设置会话名:
session_name('mysession');(所有入口统一) - 确保
session.gc_maxlifetime与 Redis 的setexTTL 完全一致(例如都设为 1440 秒) - 若用
ini_set()动态设置,务必在脚本最顶部执行,且不能被条件语句包裹
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











