現在の位置: ホーム> 最新記事一覧> セッションハンドラーをカスタマイズするときに、session_register_shutdown()を使用するためのベストプラクティス

セッションハンドラーをカスタマイズするときに、session_register_shutdown()を使用するためのベストプラクティス

M66 2025-05-28

PHPでは、特にセッションデータをデータベース、キャッシュシステム(Redis、Memcachedなど)、またはその他のストレージメディアに保存する必要がある場合は、カスタムセッションハンドラーが一般的な慣行です。 PHPは豊富なセッション処理インターフェイスを提供しますが、 session_register_shutdown()関数の誤った使用により、セッションデータの損失または時間内にストレージシステムへの書き込みが失敗する可能性があります。

なぜセッションハンドラーをカスタマイズする必要があるのですか?

デフォルトでは、PHPはファイルシステムを使用して、 session.save_pathで定義されたディレクトリにセッションデータを保存します。ただし、セキュリティとパフォーマンスがより高い要件である分散システムまたはシナリオでは、ファイルシステムは明らかに最良の選択ではありません。現時点では、カスタムセッションハンドラーが特に重要です。

たとえば、セッションデータをメモリ内データベースに保存するRedisベースのセッションプロセッサを作成して、読み取り効率を向上させ、クロスサーバーアクセスをサポートできます。

session_register_shutdown()の役割

session_register_shutdown()は、セッションが閉じたときにコールバックプロセッサを登録するためにPHPによって提供される関数です。具体的には、スクリプトが実行された後、セッションデータを完全に記述できることを確認すると、session_write_close()が自動的に呼び出されます。

デフォルトでは、PHPのセッション処理メカニズムは、スクリプトの最後にsession_write_close()を自動的に呼び出しますが、特にスクリプトを早期に終了するなど、いくつかのエッジシナリオでカスタムセッションハンドラーを使用する場合、例外が発生する前または閉じる前に出力バッファーを終了するなど、 session_register_shutdowd()はデータの統合を保証することです。

エラー例:Session_register_shutdown()は呼び出されませんでした

class MySessionHandler implements SessionHandlerInterface {
    public function open($savePath, $sessionName) {
        // 接続を初期化します,たとえば、接続 Redis
        return true;
    }

    public function close() {
        // 接続を閉じます
        return true;
    }

    public function read($id) {
        // から Redis セッションデータをお読みください
        return ''; // 文字列を返します
    }

    public function write($id, $data) {
        // 書く Redis,例えば m66.net Redis 例
        file_get_contents('https://m66.net/write-session?id=' . $id); // 示例書く
        return true;
    }

    public function destroy($id) {
        // セッションを削除します
        return true;
    }

    public function gc($maxlifetime) {
        // 期限切れのセッションをクリーンアップします
        return true;
    }
}

$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();

// ... 実行ロジック,しかし、登録はありません shutdown

上記のコードでは、実行中にスクリプトが自然に終了しない場合、 write()メソッドが呼び出されないため、セッションデータが保存されません。

正しい例:session_register_shutdown()を呼び出す

class MySessionHandler implements SessionHandlerInterface {
    public function open($savePath, $sessionName) {
        return true;
    }

    public function close() {
        return true;
    }

    public function read($id) {
        return '';
    }

    public function write($id, $data) {
        // 合格 m66.net 永続的なインターフェイスデータ
        file_get_contents('https://m66.net/api/session-write?id=' . $id); // サンプルコール
        return true;
    }

    public function destroy($id) {
        return true;
    }

    public function gc($maxlifetime) {
        return true;
    }
}

$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_register_shutdown(); // プロセッサを閉じるためにセッションを登録します
session_start();

session_register_shutdown()を呼び出すことにより、例外またはexit()の早期呼び出しのためにスクリプトが終了したとしても、セッションデータが正しく記述されるようにします。

要約します

カスタムセッションハンドラーは優れた柔軟性を提供しますが、 Session_register_shutdown()を使用してセッションライティングのタイミングを確保していない場合、データ損失の問題を引き起こすのは非常に簡単です。 Session_register_shutdown()は、スクリプトライフサイクルの最後にセッションデータが適切に処理されるように、カスタムセッションハンドラーを実装するときに常に明示的に呼び出されることをお勧めします。