在debian系统上(据我所知,这也适用于ubuntu),默认情况下禁用PHP会话的垃圾回收器。
php.ini中的相应设置是session.gc_probability = 0 ,当设置为大于零的垃圾回收器时,该设置将使能垃圾回收器。 PHP中的默认值为1 ,因此在每个PHP脚本调用时,以1/100的概率调用垃圾回收器。
在debian系统上,由于会话存储的默认路径对于Web服务器进程不可写(而且也不应该是),因此该设置被禁用。 删除过期会话文件是由系统cron作业完成的。
从php.ini中传出:
; This is disabled in the Debian packages, due to the strict permissions ; on /var/lib/php5. Instead of setting this here, see the cronjob at ; /etc/cron.d/php5, which uses the session.gc_maxlifetime setting below. ; php scripts using their own session.save_path should make sure garbage ; collection is enabled by setting session.gc_probability ;session.gc_probability = 0
由于此设置对于使用默认php会话处理(文件)的脚本而言,当您使用自己的会话处理来定义自己的会话读取和使用session_save_handler()的例程时,可能会导致问题。 在大多数情况下,这些会话管理类将为垃圾收集器提供自己的功能。
问题是,这个垃圾收集器功能将永远不会在具有上述php.ini设置的debian系统上调用。 当会话数据存储在MEMORY类型的MySQL数据库中时,这一点至关重要。 这个表的大小受到MySQL配置值max_heap_table_size的限制。 如果达到这个大小,所有进一步的会话写作都将失败,并且可能网站无法正常工作。
知道这一点,在您自己的会话管理类中覆盖垃圾收集的php.ini设置是非常重要的。 我会用一个会话管理类的小例子来显示(没有真正的写/读):
class session { function __destruct() { session_write_close(); } function __construct() { @ini_set("session.use_trans_sid","0"); @ini_set('session.gc_probability', 1); // in debian this is disabled by default... // enable customized session handler functions session_set_save_handler(array(&$this,"_sess_open"), array(&$this,"_sess_close"), array(&$this,"_sess_read"), array(&$this,"_sess_write"), array(&$this,"_sess_destroy"), array(&$this,"_sess_gc")); @session_start(); } // declare user defined session handler functions function _sess_open($sSavePath, $sSessionName) { return true; } function _sess_close() { return true; } function _sess_read($sKey) { // read and return value } function _sess_write($sKey, $val) { // write new value } function _sess_destroy($sKey) { // destroy session } function _sess_gc($iMaxLifeTime) { // delete old sessions (from db) } } $mySession = new session();
重要的是在构造函数中调用@ini_set('session.gc_probability',1) 。 此后,会话垃圾收集应按预期工作,即使在具有自己的会话管理类的debian系统上也是如此。