Hướng dẫn php garbage collection session

(PHP 7 >= 7.1.0, PHP 8)

Show

session_gcPerform session data garbage collection

Description

session_gc(): int|false

Probability based GC works somewhat but it has few problems. 1) Low traffic sites' session data may not be deleted within the preferred duration. 2) High traffic sites' GC may be too frequent GC. 3) GC is performed on the user's request and the user will experience a GC delay.

Therefore, it is recommended to execute GC periodically for production systems using, e.g., "cron" for UNIX-like systems. Make sure to disable probability based GC by setting session.gc_probability to 0.

Parameters

This function has no parameters.

Return Values

session_gc() returns number of deleted session data for success, false for failure.

Old save handlers do not return number of deleted session data, but only success/failure flag. If this is the case, number of deleted session data became 1 regardless of actually deleted data.

Examples

Example #1 session_gc() example for task managers like cron

// Note: This script should be executed by the same user of web server process.

// Need active session to initialize session data storage access.

session_start();// Executes GC immediately
session_gc();// Clean up session ID created by session_gc()
session_destroy();
?>

Example #2 session_gc() example for user accessible script

// Note: session_gc() is recommended to be used by task manager script, but
// it may be used as follows.

// Used for last GC time check

$gc_time '/tmp/php_session_last_gc';
$gc_period 1800;session_start();
// Execute GC only when GC period elapsed. 
// i.e. Calling session_gc() every request is waste of resources. 
if (file_exists($gc_time)) {
    if (
filemtime($gc_time) < time() - $gc_period) {
        
session_gc();
        
touch($gc_time);
    }
} else {
    
touch($gc_time);
}
?>

See Also

  • session_start() - Start new or resume existing session
  • session_destroy() - Destroys all data registered to a session
  • session.gc_probability

There are no user contributed notes for this page.

From the PHP manual, session.gc_probability and session.gc_divisor state that gc will occur based on this probability. I get that.

What I'm not clear on is whether this probability is on a session by session basis or overall.

So if my probability is 1% (1/100) that GC will occur, does that mean that if one session keeps getting extended, each time there is a 1% change that specific session will be cleaned up? Or does this mean that 1% of all existing sessions (as well as new ones) will trigger GC for all other existing sessions?

I'm pretty sure it's the latter, I just want to make sure.

The purpose of this question is that on our site, I want users to have long-term sessions (6 months). If 1% of all sessions trigger GC, then that effectively removes the purpose of having that long-term session, as GC will end up occurring every hour or two.

Kara

6,01416 gold badges50 silver badges57 bronze badges

asked Oct 19, 2011 at 22:26

Hướng dẫn php garbage collection session

3

Every time a PHP script is executes and starts session there is a probability that it will sweep through the session folder killing off old session.

Cleanup will only delete sessions which were not accessed within a certain time. However PHP does not guarantee that the session WILL be destroyed within that time.

Your long-term session strategy should work just fine, but you might want to reduce 1% to something like 0.1%

Another thing to look out for is that operating system might clean up your /tmp folder during reboot so even if PHP won't do it.

answered Oct 19, 2011 at 22:32

romaninshromaninsh

10.5k4 gold badges47 silver badges70 bronze badges

5

last time I looked at the source each call to session_start() "rolled the dice" so to speak, using the divisor and probability. If you hit, then it would delete all files from the session.save_path directory that were older than session.gc_maxlifetime. I forget if it used modification or access time of the file, although it shouldn't matter in normal curcumstances because php overwrites the session file by default at the end of script execution, so mod and access times should almost always match very closely.

// Rough psuedo code of how php's session_start() function works regarding garbage collection.
function session_start() {
    $percentChanceToGC = 100 * ini_get('session.gc_probability') / ini_get('session.session.gc_divisor');
    $shouldDoGarbageCollection = rand(1, 100) < $percentChanceToGC;
    if ($shouldDoGarbageCollection) {
        $expiredCutoffTime = time() - ini_get('session.gc_maxlifetime');
        foreach (scandir(ini_get('session.save_path')) as $sessionFile) {
            if (filemtime($sessionFile) < $expiredCutoffTime) {
                unlink($sessionFile);
            }
        }
    }

    // ... rest of code ....
}

I don't know how many session files you're going to end up having hang around if you want them to live for a minimum of 6 months. Consider it may take a little while for php to stat many thousands of files to determine their age. Maybe consider other options for durable storage of this data. Or you could disable php gc and just run a cron job to delete stale session files. Otherwise, that 1% of requests are gonna trigger gc and have to wait for php; in other words it could possibly lag.

answered Oct 19, 2011 at 23:04

Hướng dẫn php garbage collection session

goatgoat

30.7k7 gold badges70 silver badges96 bronze badges

I'm not an expert on this, but from reading the manual, I'd draw your attention to another setting, session.gc_maxlifetime. From the docs:

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).

So if you set this setting to a suitable value (60 * 60 * 24 * 365 / 2 for half a year, so 15768000), then the appropriate data won't be eligible for garbage collection, no matter what the other settings are.

answered Oct 19, 2011 at 22:32

lonesomedaylonesomeday

227k49 gold badges311 silver badges313 bronze badges

3