繁体   English   中英

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

[英]PHP - ini_set('session.gc_maxlifetime', 5) - Why it doesn't end the session?

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。

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

谢谢

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

假设您使用的是标准的基于文件的会话处理程序(包含$_SESSIONserialize() '副本),这就是发生的情况。

  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;

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

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

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

阅读手册 (强调我的):

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。

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

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

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

(强调我的)

在您的情况下,会话仍然是活动的。 因此,我认为它不会受到垃圾收集。

您可以尝试在sleep()之前执行session_write_close() ()。 这可能会增加垃圾收集器的概率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM