Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - ini_set('session.gc_maxlifetime', 5) - Why it doesn't end the session?

The PHP script is as follows:

<?php // continue.php
ini_set('session.gc_maxlifetime', 5);
session_start();
echo ini_get('session.gc_maxlifetime');
// wait for 7 seconds
usleep(7000000);
if (isset($_SESSION['username']))
{
    $username = $_SESSION['username'];
    $password = $_SESSION['password'];
    $forename = $_SESSION['forename'];
    $surname  = $_SESSION['surname'];

    echo "Welcome back $forename.<br />
          Your full name is $forename $surname.<br />
          Your username is '$username'
          and your password is '$password'.";
}
else echo "Please <a href=authenticate2.php>click here</a> to log in.";

?>

Based on the timeout (i.e. 5 seconds), the script should not print out anything. However, I still receive the following message

5Welcome back Bill. Your full name is Bill Smith. Your username is 'bsmith' and your password is 'mysecret'.

It seems that the line ini_set('session.gc_maxlifetime', 5) doesn't work as it should be. I am using windowsXP + XAMMP.

May you tell me how to make it work?

Thank you

like image 570
q0987 Avatar asked Aug 06 '10 22:08

q0987


3 Answers

Even if the garbage collector kicked in and deleted the session file you opened/read with session_start(), it will NOT reach into the guts of that particular PHP process and delete the $_SESSION object array.

Assuming you're on the standard file-based session handler (which contains a serialize()'d copy of $_SESSION), here's what happens.

  1. The session file sits in its temp directory
  2. You session_start(), causing PHP to open/lock the file, read its contents, deserialize the data, and incidentally, possibly update the session file's "last used" timestamp (atime on Unix boxes).
  3. If the stars and moon are aligned correctly with Neptune ascendant in the fifth house, the session garbage collector MAY fire up and delete old session files.
  4. The garbage collector will happily iterate through the session directory, and delete any files which are older than the max_liftime, BUT WILL NOT DELETE ANY FILES CURRENTLY OPEN/IN USE. Since you've not closed()'d your session, your session's file is still in use, so will not get deleted.

Now, if you did something like this:

ini_set(...); // set GC probability to max, short session lifetime, etc...

session_start(); // populate $_SESSION
session_write_close(); // dump $_SESSION out to file, close file, release lock.

sleep(7); // Sleep for 7 seconds;

session_start(); // re-populate $_SESSION;

Now you might just end up with a fresh blank $_SESSION, IF the garbage collector decides to kick in. However, unless you do that second session_start(), the old $_SESSION data from the previous start() call WILL STILL BE PRESENT. The session file may have been trashed, but the garbage collector will not touch what's present in your script's memory as it runs.

like image 165
Marc B Avatar answered Nov 16 '22 12:11

Marc B


session.gc_maxlifetime is the number of seconds after which the session will be considered for garbage collection.

session.gc_probability and session.gc_divisor then determine the probability that garbage collection will be executed on any session initialization

like image 27
Mark Baker Avatar answered Nov 16 '22 13:11

Mark Baker


Read the manual (emphasis mine):

session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Garbage collection may occur during session start (depending on session.gc_probability and session.gc_divisor).

In the same page:

session.gc_divisor coupled with session.gc_probability defines the probability that the gc (garbage collection) process is started on every session initialization. The probability is calculated by using gc_probability/gc_divisor, e.g. 1/100 means there is a 1% chance that the GC process starts on each request. session.gc_divisor defaults to 100.

Now do the math and see that it's not very likely the GC will be called on each request.

You should store the in the session a variable that saves the time of the last activity of the user and use that instead of the session is logically "active". Don't rely on garbage collection.

like image 5
Artefacto Avatar answered Nov 16 '22 13:11

Artefacto