我正在尝试重新加载页面后重新启动过期的会话。这是最小的代码示例:
<?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();
,所以我希望它能再次创建一个新会话,但是这没有发生。我必须单击两次“重新加载”,会话才能重新开始。
是否有一种方法可以在单页加载时重新启动会话?
答案 0 :(得分:1)
虽然不能100%确定这一点。我怀疑原因是setcookie
。
这里有更深入的解释:
session_destroy()销毁与当前会话关联的所有数据。它不会取消设置与该会话相关联的任何全局变量,也不会取消设置会话Cookie 。要再次使用会话变量,必须调用session_start()。
现在这是问题所在:
Cookie位于用户的浏览器中,只能在浏览器中设置或销毁。
setcookie
基本上是一种便利功能,它设置适当的标头来设置/取消设置cookie,因此,在发送响应之前,它对用户cookie并没有实际影响。
这是我正在猜测的事情:
session_destroy
删除了所有会话数据,但保留了会话cookie。 session_start
重用了相同的cookie,但现在没有任何会话数据。session_destroy/session_start
组合之后添加的所有数据都会丢失。 这可能会起作用。
在销毁会话时生成新的会话ID。希望这将生成一个新的会话cookie:
session_regenerate_id(true);
在实际重新启动会话之前反映计划的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会话内部工作原理的人那里得到更可靠的答复。