Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】SessionHandler::gc()メソッドの使い方

gcメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

gcメソッドは、セッションのガベージコレクション(不要になったセッションデータの削除)を実行するメソッドです。このメソッドは、PHPのセッション管理において非常に重要な役割を担っており、特に開発者がカスタムセッションハンドラを作成する際に、必ず実装する必要があるものです。

主な目的は、有効期限が切れたセッションデータをストレージから物理的に削除し、サーバーのリソースを無駄に消費しないようにすることです。引数として $max_lifetime を整数で受け取りますが、これはセッションデータが有効であるとみなされる最大秒数を表します。PHPは、この $max_lifetime を超えて存続しているセッションデータを古いものとみなし、削除の対象とします。

通常、PHPは session.gc_probability および session.gc_divisor といった設定値に基づいて、この gc メソッドを自動的に呼び出すことがあります。これにより、開発者が明示的にガベージコレクションを呼び出さなくても、古いセッションデータが定期的にクリーンアップされる仕組みが提供されています。

メソッドの実行が成功した場合、ガベージコレクションによって削除されたセッションの数を整数で返します。何らかの理由で処理が失敗した場合は、false を返します。セッションデータの肥大化を防ぎ、サーバーのリソースを適切に管理することで、システム全体の安定稼働に貢献する不可欠な機能です。

構文(syntax)

1<?php
2
3// SessionHandler クラスのインスタンスを作成します。
4$sessionHandler = new SessionHandler();
5
6// gc メソッドを呼び出します。
7// $max_lifetime には、セッションの最大生存期間を秒単位で整数値で指定します。
8$maxLifetime = 1440; // 例: 24分
9$sessionHandler->gc($maxLifetime);

引数(parameters)

int $max_lifetime

  • int $max_lifetime: セッションが破棄されるまでの最大生存期間(秒)を指定する整数

戻り値(return)

bool

SessionHandler::gc メソッドは、セッションガベージコレクションの実行結果を返します。成功した場合は true を、失敗した場合は false を返します。

サンプルコード

PHPセッションGCのタイミングとクラス拡張

1<?php
2
3/**
4 * MySessionHandler は PHP のデフォルトセッションハンドラである SessionHandler を継承し、
5 * セッションのガベージコレクション (GC) 処理をカスタマイズする例です。
6 *
7 * システムエンジニアを目指す初心者が、PHP のセッションGCがどのように動作し、
8 * いつ呼び出される可能性があるかを理解するのに役立つよう設計されています。
9 */
10class MySessionHandler extends SessionHandler
11{
12    /**
13     * ガベージコレクション (GC) の処理を行います。
14     * PHPのセッション管理機構によって、古いセッションデータを削除するために定期的に呼び出されます。
15     *
16     * 開発者が SessionHandler::gc メソッドを直接呼び出すことは一般的ではありません。
17     * 通常は PHP のセッション設定(php.ini の session.gc_probability, session.gc_divisor)に基づき、
18     * session_start() が呼び出された際に自動的に実行される可能性があります。
19     *
20     * @param int $max_lifetime セッションの最大有効期間(秒)。これより古いセッションは削除対象となります。
21     * @return bool GC処理が成功した場合は true、失敗した場合は false を返します。
22     */
23    public function gc(int $max_lifetime): bool
24    {
25        // ここにガベージコレクションの具体的なロジックを実装します。
26        // 例えば、データベースから古いセッションを削除したり、
27        // カスタムファイル保存場所に保存された古いセッションファイルを削除したりします。
28        //
29        // このサンプルでは、GC処理が行われたことをログに出力するにとどめ、
30        // 実際のセッションデータ削除はシミュレーションとします。
31        // 実際のアプリケーションでは、ここに具体的な削除クエリやファイル操作を記述します。
32
33        $currentTime = time();
34        $expirationThreshold = $currentTime - $max_lifetime;
35
36        error_log(
37            sprintf(
38                "[%s] MySessionHandler::gc が呼び出されました。対象の最大有効期間: %d秒。期限切れ基準タイムスタンプ: %d。\n",
39                date('Y-m-d H:i:s'),
40                $max_lifetime,
41                $expirationThreshold
42            )
43        );
44
45        // 例: データベースセッションの場合、以下のようなSQLを実行
46        // global $pdo; // データベース接続オブジェクトを想定
47        // $stmt = $pdo->prepare('DELETE FROM sessions WHERE last_activity < ?');
48        // $stmt->execute([$expirationThreshold]);
49
50        // デフォルトのファイルベースのGC処理を利用する場合は、親クラスのメソッドを呼び出します。
51        // return parent::gc($max_lifetime);
52
53        // 独自のGCロジックが成功したと仮定して true を返します。
54        return true;
55    }
56
57    // open, close, read, write, destroy メソッドは、
58    // 明示的にオーバーライドしない限り、親クラス (SessionHandler) のデフォルト実装が使用されます。
59    // デフォルトではファイルベースのセッション管理が行われます。
60    // カスタムのセッション保存メカニズム(例: データベース)を使用する場合は、
61    // これらのメソッドも適切にオーバーライドする必要があります。
62}
63
64// -----------------------------------------------------------------------------
65// カスタムセッションハンドラの登録と利用
66// -----------------------------------------------------------------------------
67
68// カスタムセッションハンドラのインスタンスを作成します。
69$customSessionHandler = new MySessionHandler();
70
71// PHP にカスタムセッションハンドラを使用するように設定します。
72// 第2引数を true に設定することで、セッション関数 (session_start() など) が
73// このハンドラのメソッドを呼び出すようになります。
74session_set_save_handler($customSessionHandler, true);
75
76// セッションのガベージコレクションの「タイミング」は、主に PHP の設定 (php.ini) に依存します。
77//
78// 1. `session.gc_probability` (分子) と `session.gc_divisor` (分母):
79//    GCが実行される確率を制御します。例えば、`session.gc_probability = 1`、
80//    `session.gc_divisor = 1000` の場合、1/1000 の確率でGCが実行されます。
81//    この確率が満たされた場合に、`session_start()` 呼び出し時に `MySessionHandler::gc()` が実行されます。
82// 2. `session.gc_maxlifetime`:
83//    セッションの最大有効期間(秒)を定義します。この値が `MySessionHandler::gc()` メソッドの
84//    `$max_lifetime` 引数として渡され、古いセッションを識別するための基準となります。
85//
86// これらの設定により、`session_start()` が呼び出された際に、
87// 設定された確率で `MySessionHandler::gc()` メソッドが自動的に呼び出される可能性があります。
88
89// セッションを開始します。
90// この `session_start()` の呼び出し時に、PHPの設定に基づいて
91// `MySessionHandler::gc()` が呼び出される可能性があります。
92session_start();
93
94// セッション変数を設定または読み込みます。
95if (!isset($_SESSION['example_count'])) {
96    $_SESSION['example_count'] = 1;
97    echo "セッションが開始されました。カウンタを1に設定しました。\n";
98} else {
99    $_SESSION['example_count']++;
100    echo "現在のセッションカウンタ: " . $_SESSION['example_count'] . "\n";
101}
102
103// スクリプトの実行が終了すると、セッションは自動的に閉じられ、データが保存されます。
104// 必要に応じて `session_write_close()` を明示的に呼び出すこともできます。
105// session_write_close();
106
107echo "スクリプトの実行が完了しました。\n";
108
109// PHPの実行環境や php.ini の設定によっては、MySessionHandler::gc() のログが毎回出力されないことに注意してください。
110// これは GC の実行が確率に基づいているためです。
111// GCの実行確率を上げるには、一時的に `ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 1);`
112// と設定することも可能ですが、これは本番環境での推奨設定ではありません。

このPHPのサンプルコードは、システムエンジニアを目指す初心者向けに、PHPのセッション管理におけるガベージコレクション(GC)の仕組みと、そのカスタマイズ方法を解説しています。SessionHandler::gcメソッドは、有効期限が切れた古いセッションデータを削除するために、PHPのセッション管理機構によって定期的に呼び出される機能です。

サンプルでは、SessionHandlerを継承したMySessionHandlerクラスを作成し、gcメソッドをオーバーライドしています。このgcメソッドは、セッションの最大有効期間を秒単位で示すint $max_lifetimeという引数を受け取ります。この値を使って、指定された期間より古いセッションデータを識別し、削除処理を実行します。メソッドの戻り値boolは、GC処理が成功した場合はtrue、失敗した場合はfalseを示します。

開発者がgcメソッドを直接呼び出すことは一般的ではなく、PHPのsession_start()関数が呼び出された際に、php.iniで設定されたsession.gc_probability(実行確率の分子)とsession.gc_divisor(確率の分母)に基づいて、自動的に実行される可能性があります。また、session.gc_maxlifetimeの値がgcメソッドの$max_lifetime引数として渡されます。サンプルコードは、GCが呼び出されたことをログに出力するシンプルな実装ですが、実際にはデータベースやファイルシステムから古いセッションを削除する具体的なロジックを記述します。session_set_save_handler関数でMySessionHandlerのインスタンスを登録することで、PHPのセッション機能はこのカスタムハンドラを利用するようになります。

このgcメソッドは、開発者が直接呼び出すことは一般的ではなく、PHPのセッション管理機構がsession_start()実行時に自動的に呼び出す可能性があります。この自動呼び出しは、php.inisession.gc_probabilitysession.gc_divisorで設定された確率に基づいて実行されます。引数の$max_lifetimeにはphp.inisession.gc_maxlifetimeで指定された値が渡されます。カスタムセッションハンドラを実装する際は、gcだけでなく、セッションの読み書きを行うreadwriteメソッドなども必要に応じてオーバーライドしてください。サンプルコードを実行しても、GCのログが毎回出力されるわけではありませんが、これはGCが確率的に実行されるためであり、異常ではありません。

PHPカスタムセッションハンドラでGCを実装する

1<?php
2
3/**
4 * カスタムセッションハンドラの例
5 * SessionHandlerInterface を実装し、PHP のセッション処理をカスタマイズします。
6 * このクラスは、セッションの保存、読み込み、削除、そしてガベージコレクションの
7 * ロジックを独自に定義するために使用されます。
8 */
9class MySessionHandler implements SessionHandlerInterface
10{
11    /**
12     * セッションを開きます。
13     * このメソッドは、セッションが開始されたときに呼び出されます。
14     * (例: session_start() の実行時)。
15     * 通常、データベース接続の確立や、セッション保存ディレクトリの検証などを行います。
16     *
17     * @param string $path セッションの保存パス
18     * @param string $name セッション名
19     * @return bool 成功した場合は true、失敗した場合は false
20     */
21    public function open(string $path, string $name): bool
22    {
23        // 実際にはここでセッションストレージ(例: DB接続)を開く処理を記述します。
24        // error_log("SessionHandler::open called. Path: {$path}, Name: {$name}");
25        return true;
26    }
27
28    /**
29     * セッションを閉じます。
30     * このメソッドは、セッションが終了したときに呼び出されます。
31     * (例: スクリプトの終了時、または session_write_close() の実行時)。
32     * 通常、open() で確立したリソース(例: DB接続)を解放します。
33     *
34     * @return bool 成功した場合は true、失敗した場合は false
35     */
36    public function close(): bool
37    {
38        // 実際にはここでセッションストレージ(例: DB接続)を閉じる処理を記述します。
39        // error_log("SessionHandler::close called.");
40        return true;
41    }
42
43    /**
44     * セッションデータを読み込みます。
45     * このメソッドは、指定されたセッションIDに対応するデータをストレージから読み込みます。
46     *
47     * @param string $id セッションID
48     * @return string 読み込んだセッションデータ(シリアライズされた形式)、またはデータがない場合は空文字列
49     */
50    public function read(string $id): string
51    {
52        // 実際にはここでセッションIDをキーとしてセッションデータをストレージから読み込みます。
53        // error_log("SessionHandler::read called. ID: {$id}");
54        // 簡略化のため、ここでは常に空文字列を返します。
55        return '';
56    }
57
58    /**
59     * セッションデータを書き込みます。
60     * このメソッドは、指定されたセッションIDとデータをストレージに保存します。
61     *
62     * @param string $id セッションID
63     * @param string $data セッションデータ(シリアライズされた形式)
64     * @return bool 成功した場合は true、失敗した場合は false
65     */
66    public function write(string $id, string $data): bool
67    {
68        // 実際にはここでセッションIDとデータをストレージに保存します。
69        // error_log("SessionHandler::write called. ID: {$id}, Data: {$data}");
70        return true;
71    }
72
73    /**
74     * セッションを破棄します。
75     * このメソッドは、session_destroy() が呼び出されたときに、
76     * 指定されたセッションIDに対応するデータをストレージから削除します。
77     *
78     * @param string $id 破棄するセッションID
79     * @return bool 成功した場合は true、失敗した場合は false
80     */
81    public function destroy(string $id): bool
82    {
83        // 実際にはここで指定されたセッションIDのデータをストレージから削除します。
84        // error_log("SessionHandler::destroy called. ID: {$id}");
85        return true;
86    }
87
88    /**
89     * セッションのガベージコレクション(古いセッションデータの削除)を行います。
90     * このメソッドは、PHP のセッションガベージコレクションプロセスによって自動的に呼び出されます。
91     * 引数 $max_lifetime は、セッションの最大有効期間(秒)を示します。
92     * この期間よりもアクセスが古いセッションデータを削除するロジックを実装します。
93     *
94     * @param int $max_lifetime セッションの最大有効期間(秒)。この期間を超えたセッションは削除対象となる。
95     * @return bool 成功した場合は true、失敗した場合は false
96     */
97    public function gc(int $max_lifetime): bool
98    {
99        // ここに古いセッションデータを削除する具体的なロジックを実装します。
100        // 例えば、データベースに保存しているセッションであれば、
101        // 最終アクセス時刻が (time() - $max_lifetime) よりも古いレコードを削除します。
102        // ファイルに保存している場合は、ファイル更新日時をチェックして古いファイルを削除します。
103
104        // 以下は、このメソッドが呼び出されたことを示すための出力です。
105        // 実際の運用では、この出力はログファイルに記録されるべきです。
106        echo "SessionHandler::gc called. Cleaning up sessions older than {$max_lifetime} seconds.\n";
107
108        // 例: 擬似的な削除処理のログ出力
109        // $timestamp_threshold = time() - $max_lifetime;
110        // error_log("Deleting sessions last accessed before: " . date('Y-m-d H:i:s', $timestamp_threshold));
111
112        // 実際の削除処理が成功したと仮定して true を返します。
113        return true;
114    }
115}
116
117// ---- カスタムセッションハンドラの利用例 ----
118
119// 1. カスタムセッションハンドラのインスタンスを作成します。
120$handler = new MySessionHandler();
121
122// 2. session_set_save_handler() を使って、このハンドラを登録します。
123//    第2引数の `true` は、PHP のシャットダウン処理時に自動的にハンドラの close() が呼ばれるようにします。
124session_set_save_handler($handler, true);
125
126// 3. PHP のセッションガベージコレクションの設定を行います。
127//    これにより、`gc` メソッドが呼び出される確率とタイミングを制御できます。
128//    ここではデモンストレーションのため、GCがより頻繁に実行されるように設定しています。
129//    通常は php.ini で設定するか、本番環境では慎重に調整します。
130ini_set('session.gc_probability', 1); // 確率分子: 1
131ini_set('session.gc_divisor', 1);     // 確率分母: 1 (つまり 1/1 の確率でGCが実行される)
132ini_set('session.gc_maxlifetime', 60); // セッションの最大有効期間を60秒に設定 (gc メソッドに渡される値)
133
134// 4. セッションを開始します。これにより、open(), read() メソッドが呼び出される可能性があります。
135session_start();
136
137// セッションデータの操作
138if (!isset($_SESSION['counter'])) {
139    $_SESSION['counter'] = 0;
140}
141$_SESSION['counter']++;
142
143echo "Session ID: " . session_id() . "\n";
144echo "Session counter: " . $_SESSION['counter'] . "\n";
145echo "--- Script End ---\n";
146
147// スクリプトの終了時に session_write_close() が自動的に呼び出され、
148// write() および close() メソッドが実行されます。
149// また、上記の ini_set 設定により、`gc` メソッドも高確率で呼び出されます。
150// `SessionHandler::gc` が呼び出されると、その中の `echo` メッセージが表示されます。

このサンプルコードは、PHPのセッション管理機能をカスタマイズするためのSessionHandlerInterfaceを実装したMySessionHandlerクラスの例です。特にSessionHandler::gcメソッドは、PHPのセッションガベージコレクション(GC)プロセスにおいて、不要になった古いセッションデータを削除する役割を担います。

通常、PHPのセッションはファイルに保存されますが、データベースなどの外部ストレージでセッションを管理したい場合に、このインターフェースを実装して独自のセッション処理を定義します。gcメソッドは、PHPのセッション開始時などに自動的に呼び出される可能性があります。引数$max_lifetimeには、セッションの最大有効期間が秒単位で渡され、この期間よりも長くアクセスされていないセッションデータを削除する具体的なロジックをここに実装します。例えば、最終アクセス時刻がtime() - $max_lifetimeよりも古いデータベースレコードを削除する処理などです。このメソッドが正常に処理を完了した場合はtrueを、失敗した場合はfalseを返します。

サンプルコードでは、MySessionHandlerクラスのインスタンスをsession_set_save_handler()関数でPHPのセッションハンドラとして登録し、ini_set()関数でガベージコレクションの実行確率とセッションの最大有効期間を設定しています。これにより、session_start()が実行された際に、定義されたgcメソッドが高確率で呼び出され、セッションクリーンアップ処理が実行される様子を確認できます。

gcメソッドは、設定された最大有効期間を超えた古いセッションデータをストレージから実際に削除するロジックを自身で実装する必要があります。サンプルコードは動作確認が目的のため、具体的な削除処理は含まれていません。$max_lifetime引数は、削除対象とするセッションの有効期間を秒単位で指定します。セッションのガベージコレクションはsession.gc_probabilityなどのphp.ini設定によって実行頻度が決まるため、本番環境では安定運用のため慎重に調整してください。また、カスタムセッションハンドラを利用する際は、gcメソッドだけでなく、openreadwriteといったすべてのメソッドを堅牢かつ安全に実装することが重要です。

関連コンテンツ