Reputation: 15909
I'm trying to restart an expired session upon page reload. Here's a minimum code sample:
<?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>
What's happening here is that hitting the Reload link after 3 seconds destroys the session (no problem there). But since I ran session_start()
again after session_destroy();
I am expecting it to create a new session again but it's not happening. I have to click Reload twice for the session to start again.
Is there a way to restart the session on a single page load?
Upvotes: 2
Views: 431
Reputation: 40690
While not 100% certain about this. I suspect the reason is setcookie
.
Here's a more in-depth explanation:
session_destroy() destroys all of the data associated with the current session. It does not unset any of the global variables associated with the session, or unset the session cookie. To use the session variables again, session_start() has to be called.
Now here's the problem:
Cookies live in a user's browser and can only be set or destroyed within the browser.
setcookie
is basically a convenience function which sets the appropriate headers to set/unset cookies and therefore it has no actual effect on user cookies until the response has been sent.
Here's what I am speculating happened:
session_destroy
deleted all session data but retained the session cookie. session_start
re-used that same cookie but now without any session data.session_destroy/session_start
combo where lost. Here's a couple of things that might work.
Generate a new session id when you destroy the session. Hopefully this will generate a new session cookie:
session_regenerate_id(true);
Reflect projected cookie changes before actually restarting the session:
session_destroy();
foreach ($_COOKIE as $k => $v) {
setcookie($k, $v, time() - 3600, '/');
unset($_COOKIE[$k]);
}
session_start();
If nothing works you might need to trigger an immediate redirect to a page that will properly start the session followed by a redirect to the final page you need to reach:
foreach ($_COOKIE as $k => $v)
setcookie($k, $v, time() - 3600, '/');
session_destroy();
header("Location: /restartSession");
Again, I want to point out that I'm just speculating, perhaps you can get a more solid response from someone who knows the inner workings of the PHP session better.
Upvotes: 1