php会话清理靠session.gc_maxlifetime、session.gc_probability和session.gc_divisor协同实现概率触发+阈值判断,非定时精准删除;gc_maxlifetime仅设gc扫描时判定过期的时间门槛(如1800秒),不直接控制session有效期或cookie生命周期,且对redis等外部存储无效。

PHP会话清理不是“设个时间就自动准时删”,它靠一套概率触发+阈值判断的机制运行。核心在于三个参数协同工作:`session.gc_maxlifetime`、`session.gc_probability` 和 `session.gc_divisor`。只改其中一个,往往达不到预期效果。
明确 gc_maxlifetime 的真实作用
它不是 session 的“倒计时截止时间”,而是垃圾回收器(GC)判定“这个 session 文件可能过期了”的时间门槛(单位秒)。比如设为 1800(30 分钟),意思是:GC 扫描时,会删除所有最后访问时间早于「当前时间减 30 分钟」的 session 文件。
关键点:
- GC 不是每次请求都运行,只按概率触发
- 该值对 Redis/Memcached 等外部存储完全无效,它们靠自身 TTL 管理
- 修改后仅影响新创建的 session;已有文件的“最后修改时间”不会重置
- CLI 模式下 GC 不工作,此配置在命令行中基本无意义
配对设置 cookie 生命周期
服务端清理和客户端 Cookie 必须同步,否则会出现“Cookie 还在,但服务端已删数据”或“数据还在,但浏览器不发 ID”的掉线问题。
需同时控制两个参数:
-
session.cookie_lifetime:设为与
gc_maxlifetime相同的秒数(如 1800),让浏览器 Cookie 带明确的 Expires 时间戳 - 若设为 0,则 Cookie 变成会话级(关闭浏览器即失效),容易和服务端脱节
- 可通过
session_set_cookie_params(1800)在运行时设置,但必须在session_start()之前调用
调整 GC 触发频率
默认 gc_probability = 1、gc_divisor = 100,即约每 100 次 session_start() 触发一次清理。高并发站点建议降低频率,避免 GC 成为性能瓶颈:
- 生产环境可设为
gc_probability = 1、gc_divisor = 1000(千分之一概率) - 开发环境保持 1/100,便于观察清理行为
- 也可彻底禁用内置 GC(设
gc_probability = 0),改用定时任务清理文件:0 * * * * find /var/lib/php/sessions -name 'sess_*' -mmin +1800 -delete
确保配置真正生效
常见“改了没用”原因多是生效路径不对:
-
优先用 ini_set():在
session_start()前执行,如ini_set('session.gc_maxlifetime', 1800); -
php.ini 修改后必须重启服务:PHP-FPM 要
systemctl restart php-fpm,不是 reload -
确认实际生效值:用
ini_get('session.gc_maxlifetime')查看,别只信配置文件内容 - .htaccess 仅限 Apache + mod_php;Nginx 或 PHP-FPM 下无效
- Docker 或云环境注意配置加载路径,常在
/usr/local/etc/php/conf.d/下覆盖主配置
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











