PHP セッション · 1 min read · Dec 27, 2025

Debian(およびUbuntu)でカスタムセッション管理を使用する際にPHPセッションデータが削除されない

Debianシステムでは(私の知る限り、これはUbuntuにも適用されます)、PHPセッションのガベージコレクタはデフォルトで無効になっています。

php.iniの対応する設定はsession.gc_probability = 0で、0より大きい値に設定するとガベージコレクタが有効になります。PHPのデフォルト値は1で、各PHPスクリプト呼び出し時に1/100の確率でガベージコレクタが呼び出されます。

Debianシステムでは、この設定はセッションストレージのデフォルトパスがウェブサーバープロセスに書き込み可能でないため無効になっています(実際、書き込み可能であってはなりません)。古いセッションファイルの削除は、ここではシステムの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); // Debianではデフォルトで無効...
         
        // カスタマイズされたセッションハンドラ関数を有効にする
        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();
    }
 
    // ユーザー定義のセッションハンドラ関数を宣言
    function _sess_open($sSavePath, $sSessionName) {
        return true;
    }
     
    function _sess_close() {
        return true;
    }
     
    function _sess_read($sKey) {
        // 値を読み取り、返す
    }
     
    function _sess_write($sKey, $val) {
        // 新しい値を書き込む
    }
     
    function _sess_destroy($sKey) {
        // セッションを破棄
    }
     
    function _sess_gc($iMaxLifeTime) {
        // 古いセッションを削除(DBから)
    } 
}
 
$mySession = new session();

重要なのは、コンストラクタ内での@ini_set(‘session.gc_probability’, 1)の呼び出しです。これにより、独自のセッション管理クラスを使用しているDebianシステムでも、セッションガベージコレクションが期待通りに機能するはずです。

Share: X/Twitter LinkedIn

新しい投稿を受信箱で受け取る

スパムはありません。いつでも購読を解除できます。