PHP会话过期由服务端gc_maxlifetime、客户端cookie_lifetime和应用层时间戳校验三者共同决定,需同步配置并重启服务,框架还需适配存储机制。

PHP网站的会话过期时间不能只靠改一个参数就生效,它由服务端清理机制、客户端Cookie有效期和应用层逻辑三者共同决定。配置不匹配时,常出现“设了2小时却10分钟就掉线”的问题。
同步调整php.ini中的两个关键参数
这是最基础且影响全局的方式,必须同时设置以下两项,单位均为秒:
- session.gc_maxlifetime:服务器端会话数据保留的最长时间。例如设为7200(2小时),表示超过2小时未活动的会话文件可能被垃圾回收器清理;
- session.cookie_lifetime:浏览器中会话Cookie的存活时间。若设为0,则关闭浏览器即失效;设为7200,则Cookie会在2小时后自动过期。
⚠️ 注意:修改后必须重启Web服务器(如Apache)或PHP-FPM进程,reload无效。可通过phpinfo()确认当前生效值,避免被Docker容器或云环境覆盖。
在代码中动态设置(适合项目级控制)
若无法修改php.ini(如共享主机),可在脚本开头用ini_set()临时覆盖:
立即学习“PHP免费学习笔记(深入)”;
- 必须在
session_start()之前调用; - 示例:
ini_set('session.gc_maxlifetime', 3600); ini_set('session.cookie_lifetime', 3600); session_start();; - 该设置仅对当前请求有效,不影响其他页面或进程。
手动记录最后活动时间戳(精准控制空闲超时)
PHP默认的垃圾回收是概率触发,不够可靠。更稳妥的做法是在会话中存时间戳,每次请求时校验:
- 在
session_start()后检查$_SESSION['last_activity']; - 若存在且距今已超设定阈值(如1800秒),则调用
session_destroy()并跳转登录页; - 否则更新
$_SESSION['last_activity'] = time();。
这种方式不依赖GC,能真正按用户“无操作时长”判断,适合金融、后台等高安全要求场景。
ThinkPHP等框架需额外注意
以ThinkPHP为例,仅改框架配置'expire' => 7200是不够的:
- 必须确保PHP底层
session.gc_maxlifetime ≥ 框架expire值; - 若使用Redis存储Session,
gc_maxlifetime将被忽略,需靠Redis自身的TTL机制(如setex)控制; - 清空
runtime/session/目录(文件驱动)或重启PHP-FPM,否则旧会话仍沿用原设置。



















