views:

22869

answers:

6

I need to keep a session alive for 30 minutes and then kill it.

+3  A: 

Is this to log the user out after a set time? Setting the session creation time (or an expiry time) when it is registered, and then checking that on each page load could handle that.

E.g.:

$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());

// later

if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
    unset($_SESSION['example']);
}

Edit: I've got a feeling you mean something else though.

You can scrap sessions after a certain lifespan by using the session.gc-maxlifetime ini setting:

ini_set('session.gc-maxlifetime', 60*30);
Ross
session.gc-maxlifetime is probably the best way to go.
R. Bemrose
A: 
if(isSet($_SESSION['started'])){
  if((mktime() - $_SESSION['started'] - 60*30) > 0){
    //logout, destroy session etc
  }
}else{
  $_SESSION['started'] = mktime();
}
middus
+1  A: 

Ah, simply

session_set_cookie_params(1800); before session_start();

Tom
-1 The session cookie lifetime has no influence on the session lifetime.
Gumbo
In fact you can have sessions (through the use of URL parameters) even when cookies are completely disabled.
Peter Ajtai
@Tom: I feel you should update this with the correct answer.
Chris
A: 
if(isSet($_SESSION['started'])){
  if((mktime() - $_SESSION['started'] - 60*30) > 0){
    //logout, destroy session etc
  }
}else{
  $_SESSION['started'] = mktime();
}
+46  A: 

You should implement a session timeout on your own. Both options mentioned by others (session.gc_maxlifetime and session.cookie_lifetime) are not reliable. I’ll explain the reason for that.

First:

session.gc_maxlifetime
session.gc_maxlifetime specifies the number of seconds after which data will be seen as 'garbage' and cleaned up. Garbage collection occurs during session start.

But the garbage collector is only started with a probability of session.gc_probability divided by session.gc_divisor. And using the default values for that options (1 and 100 respectively), the chance is only at 1%.

Well, you could argue to simply adjust these values so that the garbage collector is started more often. But when the garbage collector is started, it will check the validity for every registered session. And that is cost-intensive.

Furthermore, when using PHP’s default session save handler files, the session data is stored in files in a path specified in session.save_path. With that session handler the age of the session data is calculated on the file’s last modification date and not the last access date:

Note: If you are using the default file-based session handler, your filesystem must keep track of access times (atime). Windows FAT does not so you will have to come up with another way to handle garbage collecting your session if you are stuck with a FAT filesystem or any other filesystem where atime tracking is not available. Since PHP 4.2.3 it has used mtime (modified date) instead of atime. So, you won't have problems with filesystems where atime tracking is not available.

So it additionally might occur that a session data file is deleted while the session itself is still considered as valid because the session data was not updated recently.

And second:

session.cookie_lifetime
session.cookie_lifetime specifies the lifetime of the cookie in seconds which is sent to the browser. […]

Yes, that’s right. This does only affect the cookie lifetime and the session itself may be still valid. But it’s the server’s task to invalidate a session, not the client’s. So this doesn’t help anything.

So to conclude: The best solution is to implement a session timeout on your own. Use a simple time stamp that denotes the time of the last activity (i.e. request) and update it with every request:

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minates ago
    session_destroy();   // destroy session data in storage
    session_unset();     // unset $_SESSION variable for the runtime
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

Updating the session data with every request does also change the session file’s modification date so that the session is not removed by the garbage collector prematurely.

You can also use an additional time stamp to regenerate the session ID periodically to avoid attacks on sessions like session fixation:

if (!isset($_SESSION['CREATED'])) {
    $_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
    // session started more than 30 minates ago
    session_regenerate_id(true);    // change session ID for the current session an invalidate old session ID
    $_SESSION['CREATED'] = time();  // update creation time
}
Gumbo
How could you alter this if you wanted to check "inactive time"? In other words, the user logs in, and as long as they continue to use the site, it will not log them out. However if they are inactive for 30 mins it will log them out?
Metropolis
@Metropolis: Use something like `$_SESSION['LAST_ACTIVITY']` similar to `$_SESSION['CREATED']` where you store the time of the last activity of the user but update that value with every request. Now if the difference of that time to the current time is larger that 1800 seconds, the session has not been used for more than 30 minutes.
Gumbo
@Gumbo isnt it better to use session_unset instead of $_SESSION = array();?
Metropolis
@Metropolis: `session_unset` does the same as `$_SESSION = array()`.
Gumbo
@Gumbo - Very well written. If you had a book i'd buy it.
Ash Burlaczenko
@Gumbo - I´m a bit confused, shouldn´t you use your code in combination with `ini_set('session.gc-maxlifetime', 1800)`? Otherwise your session information could get destroyed while your session is still supposed to be valid, at least if the ini setting is the standard 24 minutes. Or am I missing something?
jeroen
@jeron: Yes, you should. But note that *session.gc\_maxlifetime* depends on the file’s last modification date if the session save handler `files` is used. So *session.gc\_maxlifetime* should be at least equal to the life time of this custom expiration handler.
Gumbo
@Gumbo: Thanks a lot, that´s what I thought and what I already did.
jeroen