Reputation: 927
I want to know exactly when the garbage collect is going to run so I made the test script below.
<?php
ini_set('session.gc_maxlifetime',10);
ini_set('session.gc_probability',1);
ini_set('session.gc_divisor',1);
echo ini_get('session.gc_maxlifetime').'s ';
echo ini_get('session.gc_probability').'/';
echo ini_get('session.gc_divisor')."<br>";
session_start();
echo session_id();
if (isset($_SESSION['test']))
{
echo "<br>";
echo "session set";
}
$_SESSION['test'] = "works";
echo "<br>";
print_r($_SESSION);
?>
Try #1: When I first try it I get:
10s 1/1
e9isrrljuvdbr1c6vqndp1e4i7
Array ( [test] => works )
Try #2: I wait more than 10 seconds and get:
10s 1/1
e9isrrljuvdbr1c6vqndp1e4i7
session set
Array ( [test] => works )
Try #3: Then any time after that I get:
10s 1/1
e9isrrljuvdbr1c6vqndp1e4i7
Array ( [test] => works )
Why does garbage collection not kick in on try #2 but kick in on try #3?
Upvotes: 0
Views: 372
Reputation: 70863
The PHP garbage collection for session data is designed to eventually clean the data, not to guarantee it is cleaned.
If you start a session, PHP tries to find already stored session data from last request. Failing this, it will assume the session is brand new, create an empty session file on disk, lock it, and initialize $_SESSION as empty array.
At the end of the script, or when session_write_close()
is called, the contents of $_SESSION is serialized to this file, the lock is released, and the script ends.
Only then the garbage collection kicks in, with a probability (i.e. only one out of 100 requests starts the garbage collection). It scans all session files for expiration, and if a files last modification time is older that the session.gc_maxlifetime
setting, it gets deleted.
In fact, session.gc_maxlifetime
is mislabeled. It really is session.gc_minlifetime
, because the session data lives AT LEAST this amount of time.
Second thing: The garbage collection cannot throw away the session you are actively using, because it's data is freshly saved.
Third: Garbage collection needs a request to trigger it. It is not an automated process in the background.
Combining points two and three results in garbage collection cleaning away only the OTHER sessions that are old enough to be older than session.gc_maxlifetime
. To test it, you would need at least TWO sessions, one to expire, and the second to trigger executing the garbage collection.
So it should go like this: Have two browsers, access the session page with both. Reload the page in one browser regularly, wait more than session.gc_maxlifetime
seconds in the second browser. Only then reload in the second browser - session should be gone.
Upvotes: 1