Developers may notice that even when the session's lifecycle is set, old session data still persists for a long time. This is usually because session_gc() is not executed on every request.
Reason Analysis:
PHP's session cleanup mechanism is triggered probabilistically. The default configuration is as follows:
session.gc_probability = 1
session.gc_divisor = 100
This means that, on average, only 1 out of every 100 requests will trigger the GC operation.
Solution:
You can increase the GC trigger probability or manually call session_gc() to force cleanup:
ini_set('session.gc_probability', 100);
ini_set('session.gc_divisor', 100);
Alternatively, use it at the appropriate moment:
session_start();
session_gc();
Issue Description:
When using a custom session storage mechanism (such as databases, Redis, etc.), GC seems ineffective.
Reason Analysis:
If the custom SessionHandler class does not implement the gc() method correctly, PHP will not actually clean up data when calling session_gc().
Solution:
Make sure the gc() method is implemented in the SessionHandlerInterface. For example, when using MySQL to store sessions, it can be implemented as follows:
class MySessionHandler implements SessionHandlerInterface {
// ...
$stmt = $this->pdo->prepare("DELETE FROM sessions WHERE last_access < :time");
$stmt->execute([':time' => time() - $max_lifetime]);
return true;
}
}
Then register it:
$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();
Issue Description:
Even though session_gc() is called, old session files are still not deleted.
Reason Analysis:
This may be because session.save_path is pointing to the wrong directory or there are insufficient permissions.
Solution:
Make sure the correct save path is set and that the PHP process has read and write permissions:
ini_set('session.save_path', '/var/lib/php/sessions');
Check folder permissions:
sudo chown -R www-data:www-data /var/lib/php/sessions
sudo chmod 700 /var/lib/php/sessions
Issue Description:
Calling session_gc() in CLI mode (such as in scheduled scripts) has no effect or results in an error.
Reason Analysis:
The CLI environment may not have initialized the correct session configuration (e.g., save_path is empty), or the session was not initialized before the call.
Solution:
Ensure the environment is properly configured before calling session_gc():
ini_set('session.save_handler', 'files');
ini_set('session.save_path', '/var/lib/php/sessions');
session_gc();
Issue Description:
After a website has been running for a long time, a large number of .sess files are stored in the /tmp directory, taking up significant disk space.
Reason Analysis:
The garbage collection (GC) has not been performed effectively for a long time, or the GC frequency is too low, resulting in historical session data not being cleaned up.
Solution:
It is recommended to set up a dedicated scheduled task script to periodically call session_gc(), for example, to run it once every hour:
<?php
ini_set('session.save_path', '/var/lib/php/sessions');
session_gc();
Combine it with a Linux Cron job:
0 * * * * /usr/bin/php /var/www/html/session_gc.php
Issue Description:
In load balancing or reverse proxy environments, different nodes fail to synchronize session data, leading to inconsistent GC cleanup.
Solution:
It is recommended to use centralized session storage, such as Redis or a database, and unify the GC strategy:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://gitbox.net:6379');
In the Redis solution, you should periodically clean up or use Redis's expiration mechanism to automatically manage sessions.