sess_expiration不生效的主因是配置协同失效:CI4中它仅作建议值,实际依赖php.ini的session.gc_maxlifetime;CI3中则常因sess_save_path路径错误、encryption_key缺失、GC概率机制或时间单位误读导致静默失效。

sess_expiration 配置后不生效,90% 是因为没配对配套参数,或混淆了 CI3 与 CI4 的会话机制差异。
CI4 中 sess_expiration 不起作用的典型原因
CI4 已弃用全局 $config['sess_expiration'],它只在 Session 驱动为 files 且未启用数据库存储时部分生效;真正控制过期时间的是底层驱动自身的 TTL 设置,而非配置项本身。
- CI4 默认使用
CodeIgniter\Session\Handlers\FileHandler,其过期逻辑依赖 PHP 的session.gc_maxlifetime(单位秒),而非sess_expiration -
sess_expiration在 CI4 的Config/Session.php中仅作为“建议值”传给驱动,但FileHandler实际忽略它,只读取ini_get('session.gc_maxlifetime') - 若你手动改了
php.ini中的session.gc_maxlifetime = 3600,但没重启 PHP-FPM 或 Apache,修改不会生效 - CI4 的 Session 初始化发生在首次访问时,若会话已存在(如 cookie 未过期),新配置不会回溯刷新旧 session 文件的 mtime
CI3 中 sess_expiration 失效的常见误操作
CI3 的 $config['sess_expiration'] 看似简单,但极易因路径、加密或驱动初始化时机出错而静默失效。
-
sess_save_path未设为绝对路径,导致Session_files_driver初始化失败,整个 session 机制退化为无状态——此时sess_expiration形同虚设 -
encryption_key为空或长度不足,使 session ID 生成失败,$this->session->set_userdata()不写入,自然也谈不上过期 - 开启了
sess_expire_on_close = TRUE,但用户没真正关闭浏览器(现代标签页常驻后台),导致看似“不过期”,实则是会话被保活 - PHP 的
session.cookie_lifetime设为 0(默认),意味着浏览器关闭即丢 cookie;若前端 JS 或 iframe 持续发请求,cookie 会被不断续命,掩盖了sess_expiration的实际效果
跨版本共通陷阱:时间单位与时区错位
无论是 CI3 还是 CI4,sess_expiration 值都以“秒”为单位,但开发者常误以为是分钟或小时,且容易忽略服务器时区对 GC 触发的影响。
- CI3 的
sess_expiration = 300表示 5 分钟,不是 5 小时;CI4 的对应字段(如session.driverOptions.ttl)同样只认秒 - PHP 的 session GC 由概率触发:
session.gc_probability / session.gc_divisor,默认 1/100,意味着每 100 次请求才可能清理一次过期 session——所以刚过期的 session 可能仍能读取数分钟 - 服务器时间与客户端时间不同步时,cookie 的
Expires时间戳可能早于当前时间,导致浏览器直接丢弃 cookie,比服务端过期更早失效
sess_expiration + gc_maxlifetime + cookie_lifetime + 存储路径可写性 + 加密密钥有效性 这五者的协同。漏掉任意一环,都会让“设置过期时间”变成幻觉。


















