【问题标题】:Restart session upon timeout in PHP在 PHP 中超时重新启动会话
【发布时间】:2019-01-02 11:58:30
【问题描述】:

我正在尝试在页面重新加载时重新启动过期的会话。这是一个最小的代码示例:

<?php

$timeout = 3;
ini_set('session.gc_maxlifetime', $timeout);
session_name('mytest');
session_start();

if (isset($_SESSION['LAST_ACTIVE']) && (time() - $_SESSION['LAST_ACTIVE'] > $timeout))
{
    foreach ($_COOKIE as $k => $v)
        setcookie($k, $v, time() - 3600, '/');

    echo 'session cookie destroyed<br />';

    session_destroy();
    session_start();
}

$_SESSION['LAST_ACTIVE'] = time();

?>

<a href="<?=$_SERVER['PHP_SELF']?>">Reload</a>

这里发生的情况是,在 3 秒后点击重新加载链接会破坏会话(没有问题)。但是由于我在session_destroy(); 之后再次运行session_start(),我希望它再次创建一个新会话,但它没有发生。我必须单击“重新加载”两次才能重新开始会话。

有没有办法在单页加载时重新启动会话?

【问题讨论】:

    标签: php session cookies session-variables session-cookies


    【解决方案1】:

    虽然不能 100% 确定这一点。我怀疑原因是setcookie

    这里有更深入的解释:

    session_destroy() 销毁与当前会话关联的所有数据。它不会取消设置与会话关联的任何全局变量,或取消设置会话 cookie。要再次使用会话变量,必须调用 session_start()。

    现在问题来了:

    Cookie 存在于用户的浏览器中,只能在浏览器中设置或销毁。 setcookie 基本上是一个便利函数,它设置适当的标头来设置/取消设置 cookie,因此在发送响应之前它对用户 cookie 没有实际影响。

    这是我推测发生的事情:

    1. session_destroy 删除了所有会话数据,但保留了会话 cookie。
    2. session_start 重新使用了相同的 cookie,但现在没有任何会话数据。
    3. 响应已发送给客户端,然后客户端删除了请求的会话 cookie。
    4. 这意味着在 session_destroy/session_start 组合之后添加的任何数据都丢失了。

    这里有几件事可能会奏效。

    1. 销毁会话时生成新的会话 ID。希望这会生成一个新的会话 cookie:

      session_regenerate_id(true);
      
    2. 在实际重新启动会话之前反映预计的 cookie 更改:

      session_destroy();
      foreach ($_COOKIE as $k => $v) {      
          setcookie($k, $v, time() - 3600, '/');
          unset($_COOKIE[$k]);
      }
      session_start();
      

    如果没有任何效果,您可能需要触发立即重定向到将正确启动会话的页面,然后重定向到您需要到达的最终页面:

    foreach ($_COOKIE as $k => $v)
        setcookie($k, $v, time() - 3600, '/');
    
    session_destroy(); 
    header("Location: /restartSession");
    

    再次,我想指出我只是推测,也许您可​​以从更了解 PHP 会话内部工作原理的人那里得到更可靠的回应。

    【讨论】:

    • 感谢您提供的详细信息,但这些都不起作用。即使header('location: ...') 也没有用。但是,以 1 秒延迟进行手动刷新是可行的,例如 header('refresh:1; url='.$_SERVER['PHP_SELF']);,但这是意料之中的,因为它本质上是两次重新加载。
    • @apokryfos 这确实是一个深入的分析我想补充一点,使用ajax设置适当的cookie也可以是一个可能的解决方案。因为常规请求和ajax之间没有根本区别就 cookie 而言的请求。
    猜你喜欢
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多