在PHP中超时后重新启动会话

时间:2018-07-25 15:30:51

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

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

<?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秒钟后点击Reload链接会破坏会话(那里没有问题)。但是,由于我在session_start()之后又运行了session_destroy();,所以我希望它能再次创建一个新会话,但是这没有发生。我必须单击两次“重新加载”,会话才能重新开始。

是否有一种方法可以在单页加载时重新启动会话?

1 个答案:

答案 0 :(得分: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会话内部工作原理的人那里得到更可靠的答复。