Changing the PHP Session Lifetime
As anyone who has attempted to use the default PHP session handler has probably noticed, sessions naturally die after a period of inactivity.
What you’ll probably want in most situations is for the session not to die (or ‘expire’) until the user closes their browser. Unfortunately, there is no server-side way of knowing for certain when the browser is closed and can only assume it has been closed after a period of inactivity (user hasn’t made any requests).
First, let’s take a brief look at how the default PHP session handler works…
Before a session can be used, the session_start() function must be called. This function will perform the necessary steps to initialise a new session and read in any data from an existing one. In addition, this method also does some tidying up which ultimately kills your sessions prematurely.
To keep session data tidy on your server, PHP will perform some ‘garbage collection’ (GC) — that is, PHP will search for any session data that it thinks is old then deletes it. The default session handler uses a session.gc_maxlifetime configuration option which allows the application to set the lifetime of its session. This value is in seconds and defaults to 1440 (24 minutes). Therefore, any sessions that have been inactive for more than 24 minutes will be considered dead. This is not very helpful in Content Management Systems where it can take longer for the user to write their copy, only to be logged out when they come to submit the content.
One other little quirk that PHP likes to throw at you is the issue that arises when attempting to store session data with varying lifetimes in the same directory. What the default handler will do in this case is get the shortest lifetime and apply it to all sessions in the same folder. For example, let’s say you have Project A which used a session lifetime of 1440 and Project B which used 2400, both storing their session data in /tmp/sessions. It”ll save you a headache to know that Project B sessions will die after 1440 seconds. There are two obvious solutions for this: 1) create a subfolder for each project (e.g. /tmp/sessions/myproject; or 2) create a subfolder for each lifetime (e.g. /tmp/sessions/1440).
As a sidenote — to minimise the load that GC process puts on the server, PHP will not perform a GC every time the session_start() is called. Instead, the directives session.gc_probability and session.gc_divisor can be set. For example, 1 and 100, respectively, means that there is a 1-in-100 (1%) chance that PHP will perform a GC when a session is started (more information available in the PHP manual).
So, how do we change the default lifetime of 24 minutes? There are two solutions:
- Play around with a few PHP settings, either in the php.ini file or at runtime using
ini_set(), so that they have a longer lifetime - Create a custom session handler with a more complex GC strategy
In most instances you’ll probably go for the first option as it is relatively simple and probably faster than most custom solutions. So, to get you started, here is a snippet of code which will create a 24-hour session (you could class this as an ‘infinite’ session for most typical cases).
// Choose your desired lifetime $lifetime = 86400; // 24 hours // Consider sessions dead after 24 hours ini_set('session.gc_maxlifetime', $lifetime); // Store the sessions in a subdirectory based on the lifetime ini_set('session.save_path', ini_get('session.save_path') . '/' . $lifetime); // Now start the session as usual session_start();
Let us know how you get on!
