PHP - ini_set('session.gc_maxlifetime',5) - 为什么它不会结束会话?

q09*_*987 18 php session persistence

PHP脚本如下:

<?php // continue.php
ini_set('session.gc_maxlifetime', 5);
session_start();
echo ini_get('session.gc_maxlifetime');
// wait for 7 seconds
usleep(7000000);
if (isset($_SESSION['username']))
{
    $username = $_SESSION['username'];
    $password = $_SESSION['password'];
    $forename = $_SESSION['forename'];
    $surname  = $_SESSION['surname'];

    echo "Welcome back $forename.<br />
          Your full name is $forename $surname.<br />
          Your username is '$username'
          and your password is '$password'.";
}
else echo "Please <a href=authenticate2.php>click here</a> to log in.";

?>
Run Code Online (Sandbox Code Playgroud)

根据超时(即5秒),脚本不应打印任何内容.但是,我仍然收到以下消息

5Welcome back Bill. Your full name is Bill Smith. Your username is 'bsmith' and your password is 'mysecret'.
Run Code Online (Sandbox Code Playgroud)

似乎行ini_set('session.gc_maxlifetime',5)不能正常工作.我正在使用windowsXP + XAMMP.

你能告诉我如何让它发挥作用吗?

谢谢

Mar*_*c B 37

即使垃圾收集器启动并删除了您打开/读取的会话文件session_start(),它也不会触及该特定PHP进程的内容并删除$_SESSION对象数组.

假设你在标准的基于文件的会话处理程序(包含serialize()'d副本$_SESSION),这就是发生的事情.

  1. 会话文件位于其临时目录中
  2. session_start(),导致PHP打开/锁定文件,读取其内容,反序列化数据,顺便说一下,可能更新会话文件的"上次使用"时间戳(在Unix机器上的atime).
  3. 如果星星和月亮与第五宫中的海王星上升正确对齐,则会话垃圾收集器可以启动并删除旧的会话文件.
  4. 垃圾收集器将愉快地遍历会话目录,并删除任何早于max_liftime的文件,但不会删除当前打开/未使用的任何文件.由于您尚未关闭()会话,因此会话的文件仍在使用中,因此不会被删除.

现在,如果你做了这样的事情:

ini_set(...); // set GC probability to max, short session lifetime, etc...

session_start(); // populate $_SESSION
session_write_close(); // dump $_SESSION out to file, close file, release lock.

sleep(7); // Sleep for 7 seconds;

session_start(); // re-populate $_SESSION;
Run Code Online (Sandbox Code Playgroud)

现在你可能最终得到一个新的空白$ _SESSION,如果垃圾收集器决定启动.但是,除非你这样做,否则session_start()前一个start()调用的旧$ _SESSION数据将仍然存在.会话文件可能已被删除,但垃圾收集器在运行时不会触及脚本内存中的内容.

  • +1为#3和'session_write_close()`好主意! (3认同)
  • 你确定垃圾收集器在*`session_start()`填充`$ _SESSION`数组之前没有运行*吗?你有一个确认这个的URL吗? (2认同)

Mar*_*ker 9

session.gc_maxlifetime是将会话考虑进行垃圾回收的秒数.

session.gc_probability和session.gc_divisor然后确定在任何会话初始化时执行垃圾收集的概率


Art*_*cto 5

阅读手册(强调我的):

session.gc_maxlifetime指定多少秒后数据将被视为“垃圾”并可能被清除。垃圾收集可能会在会话启动期间发生(取决于session.gc_probabilitysession.gc_divisor)。

在同一页面中:

session.gc_divisor加上session.gc_probability定义了每次会话初始化时启动 gc(垃圾收集)进程的概率。概率通过使用 计算gc_probability/gc_divisor,例如 1/100 表示 GC 过程在每个请求上启动的机会为 1%。session.gc_divisor默认为 100。

现在计算一下,发现 GC 不太可能在每个请求上被调用。

您应该在会话中存储一个变量,该变量保存用户上次活动的时间,并使用该变量而不是会话在逻辑上是“活动的”。不要依赖垃圾收集。