协慌网

登录 贡献 社区

如何在 30 分钟后使 PHP 会话到期?

我需要让会话保持 30 分钟,然后将其销毁。

答案

您应该实现自己的会话超时。其他人提到的两个选项( session.gc_maxlifetimesession.cookie_lifetime )都不可靠。我会解释原因。

第一:

的 session.gc_maxlifetime
session.gc_maxlifetime指定将数据视为 “垃圾” 并清理的秒数。在会话开始期间发生垃圾收集。

但垃圾收集器只是以session.gc_probability除以session.gc_divisor的概率开始。并使用这些选项的默认值(分别为 1 和 100),机率仅为 1%。

好吧,您可以简单地调整这些值,以便更频繁地启动垃圾收集器。但是当垃圾收集器启动时,它将检查每个注册会话的有效性。这是成本密集型的。

此外,使用 PHP 的默认session.save_handler文件时,会话数据存储在session.save_path 中指定的路径中的文件中。使用该会话处理程序,会话数据的年龄将根据文件的上次修改日期计算,而不是上次访问日期:

注意:如果您使用的是基于文件的默认会话处理程序,则您的文件系统必须跟踪访问时间(atime)。如果您遇到 FAT 文件系统或任何其他无法进行 atime 跟踪的文件系统,那么 Windows FAT 不会如此,您将不得不想出另一种方法来处理垃圾收集会话。从 PHP 4.2.3 开始,它使用了 mtime(修改日期)而不是 atime。因此,对于无法进行 atime 跟踪的文件系统,您不会遇到问题。

因此,当会话本身仍然被认为是有效的时,可能还会发生会话数据文件被删除,因为会话数据最近没有更新。

第二个:

session.cookie_lifetime
session.cookie_lifetime指定发送到浏览器的 cookie 的生命周期(以秒为单位)。 [...]

恩,那就对了。这仅影响 cookie 生存期,会话本身可能仍然有效。但是服务器的任务是使会话无效,而不是客户端。所以这对任何事都没有帮助。实际上,将session.cookie_lifetime设置为0会使会话的 cookie 成为真正的会话 cookie ,该cookie仅在浏览器关闭之前有效。

结论 / 最佳解决方案:

最好的解决方案是实现自己的会话超时。使用表示最后一次活动(即请求)的时间的简单时间戳,并使用每个请求更新它:

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minutes ago
    session_unset();     // unset $_SESSION variable for the run-time 
    session_destroy();   // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

每次请求更新会话数据也会更改会话文件的修改日期,以便垃圾收集器不会过早地删除会话。

您还可以使用额外的时间戳来定期重新生成会话 ID,以避免对会话固定会话的攻击:

if (!isset($_SESSION['CREATED'])) {
    $_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
    // session started more than 30 minutes ago
    session_regenerate_id(true);    // change session ID for the current session and invalidate old session ID
    $_SESSION['CREATED'] = time();  // update creation time
}

笔记:

  • session.gc_maxlifetime应至少等于此自定义到期处理程序的生命周期(本例中为 1800);
  • 如果你想活动 ,而不是因为开始 30 分钟后的 30 分钟后到期的会议,你还需要使用setcookie与到期time()+60*30 ,以保持会话 cookie 活跃。

PHP 会话在 30 分钟内到期的简单方法。

注意:如果你想改变时间,只需用你想要的时间改变 30,不要改变 * 60:这将给出分钟。


几分钟:(30 * 60)
在几天内:(n * 24 * 60 * 60)n = 没有天


的 login.php

<?php
    session_start();
?>

<html>
    <form name="form1" method="post">
        <table>
            <tr>
                <td>Username</td>
                <td><input type="text" name="text"></td>
            </tr>
            <tr>
                <td>Password</td>
                <td><input type="password" name="pwd"></td>
            </tr>
            <tr>
                <td><input type="submit" value="SignIn" name="submit"></td>
            </tr>
        </table>
    </form>
</html>

<?php
    if (isset($_POST['submit'])) {
        $v1 = "FirstUser";
        $v2 = "MyPassword";
        $v3 = $_POST['text'];
        $v4 = $_POST['pwd'];
        if ($v1 == $v3 && $v2 == $v4) {
            $_SESSION['luser'] = $v1;
            $_SESSION['start'] = time(); // Taking now logged in time.
            // Ending a session in 30 minutes from the starting time.
            $_SESSION['expire'] = $_SESSION['start'] + (30 * 60);
            header('Location: http://localhost/somefolder/homepage.php');
        } else {
            echo "Please enter the username or password again!";
        }
    }
?>

HomePage.php

<?php
    session_start();

    if (!isset($_SESSION['luser'])) {
        echo "Please Login again";
        echo "<a href='http://localhost/somefolder/login.php'>Click Here to Login</a>";
    }
    else {
        $now = time(); // Checking the time now when home page starts.

        if ($now > $_SESSION['expire']) {
            session_destroy();
            echo "Your session has expired! <a href='http://localhost/somefolder/login.php'>Login here</a>";
        }
        else { //Starting this else one [else1]
?>
            <!-- From here all HTML coding can be done -->
            <html>
                Welcome
                <?php
                    echo $_SESSION['luser'];
                    echo "<a href='http://localhost/somefolder/logout.php'>Log out</a>";
                ?>
            </html>
<?php
        }
    }
?>

LogOut.php

<?php
    session_start();
    session_destroy();
    header('Location: http://localhost/somefolder/login.php');
?>

这是在一段时间后将用户注销吗?设置会话创建时间(或到期时间),然后检查每个页面上的负载可以处理它。

例如:

$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());

// later

if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
    unset($_SESSION['example']);
}

编辑:我觉得你的意思是别的。

您可以使用session.gc_maxlifetime ini 设置在一定生命周期后删除会话:

编辑: ini_set('session.gc_maxlifetime',60 * 30);