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

时间:2010-08-06 22:08:15

标签: 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.";

?>

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

5Welcome back Bill. Your full name is Bill Smith. Your username is 'bsmith' and your password is 'mysecret'.

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

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

谢谢

4 个答案:

答案 0 :(得分:36)

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

假设您使用的是标准的基于文件的会话处理程序(包含serialize()的{​​{1}}副本),请执行以下操作。

  1. 会话文件位于其临时目录
  2. $_SESSION,导致PHP打开/锁定文件,读取其内容,反序列化数据,顺便提一下,可能会更新会话文件的“上次使用”时间戳(Unix盒子上的atime)。
  3. 如果星星和月亮与第五宫中的海王星上升正确对齐,会话垃圾收集器 MAY 将启动并删除旧的会话文件。
  4. 垃圾收集器将很乐意遍历会话目录,并删除任何早于max_liftime的文件,但不会删除当前打开/未使用的任何文件。由于您尚未关闭()会话,因此会话的文件仍在使用中,因此不会被删除。
  5. 现在,如果你做了这样的事情:

    session_start()

    现在你可能最终得到一个新的空白$ _SESSION, IF 垃圾收集器决定启动。但是,除非你那么做第二个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; ,旧的$ _SESSION数据从上一个开始()调用将仍然存在。会话文件可能已被删除,但垃圾收集器在运行时不会触及脚本内存中的内容。

答案 1 :(得分:9)

session.gc_maxlifetime是会话将 视为 进行垃圾回收的秒数。

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

答案 2 :(得分:4)

阅读manual(强调我的):

  

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。

您应该在会话中存储一个变量,该变量可以节省用户上次活动的时间并使用该变量来代替会话在逻辑上“活动”。不要依赖垃圾收集。

答案 3 :(得分:1)

我不认为这是gc_maxlifetime应该如何运作的。手册说

  

session.gc_maxlifetime指定数据被视为“垃圾”并且可能清理的秒数。

(强调我的)

在您的情况下,会话仍处于活动状态。因此,我认为它不会被垃圾收集。

你可以尝试在睡眠前做session_write_close()()。这可能会增加垃圾收集器的概率。