PHP 会话 30 分钟后过期:3 种最佳方法 + 代码

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么你的 PHP 会话存活时间比需要的更长?

\n\n

你是否曾想过,为什么在 30 分钟无操作后,你的网站仍然记得你已经登录?或者相反,用户抱怨他们被系统“踢出”得太早了?在 PHP 中管理会话生命周期的问题,是初学者(以及不仅仅是初学者)开发者最常见的头痛问题之一。问题 "How do I expire a PHP session after 30 minutes?" 在 Stack Overflow 上获得了数千次浏览,这并非偶然。

\n\n

让我们弄清楚如何让 PHP 会话正好在 30 分钟后失效。我们将探讨三种方法:从简单(但狡猾)到专业。你将了解为什么 session.gc_maxlifetime 常常不像你预期的那样工作,以及如何编写不会让你失望的可靠代码。

\n\n

问题:什么是真正的“会话生命周期”?

\n\n

在深入代码之前,让我们先了解基础知识。PHP 会话不仅仅是一个在浏览器中滴答作响的计时器。它是服务器上的一个文件(通常在 /tmp/ 中),用于存储用户数据。“过期”会话意味着该文件被删除或变得无效。

\n\n

有三个关键因素影响生命周期:

\n\n
    \n
  • 会话 Cookie: 浏览器存储会话 ID(通常在 cookie PHPSESSID 中)。这个 cookie 有自己的生命周期。
  • \n
  • 服务器上的会话文件: 它有最后修改时间(mtime)。
  • \n
  • 垃圾回收器 (GC): PHP 会定期清理旧的会话文件,但这不是按计划进行的,而是随机进行的。
  • \n
\n\n

正是由于这种“三层”架构,导致了混乱。只设置一个参数通常不会产生预期的效果。

\n\n

方法 1:天真的方法——仅使用 session.gc_maxlifetime

\n\n

文档建议的最明显方法是设置 session.gc_maxlifetime。这似乎是问题 "How do I expire a PHP session after 30 minutes?" 的答案。但事情没那么简单。

\n\n
<?php\n// 开始会话\nsession_start();\n\n// 设置会话生命周期(秒):30 分钟 = 1800 秒\nini_set('session.gc_maxlifetime', 1800);\n\n// 将会话 cookie 的生命周期也设置为 30 分钟\nsession_set_cookie_params(1800);\n\n// 就这样?不。\n?>
\n\n

为什么这可能不起作用?

\n
    \n
  • 垃圾回收器 (GC) 很懒。 它以 session.gc_probability / session.gc_divisor(默认 1/100)的概率运行。也就是说,即使会话文件已经存在一小时,如果 GC 没有运行,它也可能不会在下一次请求时被删除。
  • \n
  • 其他应用程序。 如果服务器上运行着多个网站,它们可能会清理彼此的会话,或者相反,不清理你的会话。
  • \n
  • 缓存。 在某些主机(尤其是共享主机)上,ini_set 设置可能会被忽略。
  • \n
\n\n

结论: 这种方法是基础,但不是万能的。它只在理想条件下有效。对于生产环境,需要更深入的研究。

\n\n

方法 2:会话内的手动计时器(推荐)

\n\n

这种方法是一个折中方案。我们不是依赖垃圾回收器,而是自己控制用户最后活动的时间。这是 Stack Overflow 上关于 PHP 会话 30 分钟后过期 主题最流行的答案。

\n\n

思路很简单:在每次请求时,我们检查用户上次活动的时间。如果超过 30 分钟,则销毁会话。

\n\n
<?php\nsession_start();\n\n// 会话生命周期(秒)\n$session_lifetime = 1800; // 30 分钟\n\n// 检查是否设置了最后活动时间戳\nif (isset($_SESSION['LAST_ACTIVITY'])) {\n    // 计算与当前时间的差值                

博客

书籍推荐