非常に同時、分散、または長期にわたるPHPアプリケーションを構築する場合、従来のファイルシステムセッションストレージメソッドがセッションスパムデータの蓄積につながり、パフォーマンスと安定性に影響を与える可能性があります。この問題を解決するために、PHPはSessionHandlerInterfaceインターフェイスを提供し、開発者がセッションストレージロジックをカスタマイズできるようにします。ここでは、GC()メソッドがガベージクリーニングプロセスを制御する鍵です。
SessionHandlerInterface :: GCは、このインターフェイスで定義されたメソッドです。その機能は、セッションデータがPHP内で期限切れになってゴミ収集操作を実行することが判断された場合に呼び出されます。メソッドの署名は次のとおりです。
public function gc(int $max_lifetime): int|false;
$ max_lifetime :セッションの最大生存時間(単位:秒)を表します。
返品値:クリーン化されたセッションの数を返したり、成功したりして真のものを返し、失敗時に虚偽を返します。
ユーザーがセッションプロセッサ(カスタムセッションハンドラー)をカスタマイズし、インターフェイスを実装すると、この方法で時代遅れのセッションデータをクリーニングするポリシーを定義できます。
PHPはデフォルトでファイルベースのセッションストレージを使用し、そのGCメカニズムは確率トリガー( session.gc_probabilityとsession.gc_divisorで制御)に基づいています。これは、要求するたびにクリーニングロジックを実行しないことを意味します。
例えば:
session.gc_probability = 1
session.gc_divisor = 1000
これは、ガベージクリーニングが1/1000の確率でトリガーされることを示しています。この戦略は、トラフィックシステムの低いシステムでの期限切れのセッション蓄積を引き起こす可能性があり、これは高トラフィックシステムで頻繁にトリガーされ、パフォーマンスに影響を与える可能性があります。
以下は、データベースストレージに基づいたカスタムセッションハンドラーの例です。GC ()メソッドを最適化することでパフォーマンスを改善する方法を示しています。
class DbSessionHandler implements SessionHandlerInterface {
protected $db;
public function __construct(PDO $db) {
$this->db = $db;
}
public function open($savePath, $sessionName): bool {
return true;
}
public function close(): bool {
return true;
}
public function read($id): string|false {
$stmt = $this->db->prepare("SELECT data FROM sessions WHERE id = :id AND expires > :now");
$stmt->execute([':id' => $id, ':now' => time()]);
return (string) $stmt->fetchColumn();
}
public function write($id, $data): bool {
$expires = time() + (int)ini_get("session.gc_maxlifetime");
$stmt = $this->db->prepare("
REPLACE INTO sessions (id, data, expires) VALUES (:id, :data, :expires)
");
return $stmt->execute([
':id' => $id,
':data' => $data,
':expires' => $expires,
]);
}
public function destroy($id): bool {
$stmt = $this->db->prepare("DELETE FROM sessions WHERE id = :id");
return $stmt->execute([':id' => $id]);
}
public function gc($max_lifetime): int|false {
$stmt = $this->db->prepare("DELETE FROM sessions WHERE expires < :time");
$stmt->execute([':time' => time()]);
return $stmt->rowCount();
}
}
上記の実装では、 GC()メソッドは、データベースからすべての期限切れのセッションレコードを明示的に削除します。デフォルトの確率ベースのGCと比較して、この方法はより信頼性が高く、定期的なクリーニングを実現するためにシステムタイミングタスク(CRONなど)で使用できます。
カスタムプロセッサを定義したら、次の方法で有効にすることができます。
$handler = new DbSessionHandler($pdo);
session_set_save_handler($handler, true);
session_start();
データベースのクリーンアップスクリプトまたはタスクスケジューラを使用する場合、 session.gc_probabilityを0に設定して自動GCを完全にオフにすることができます。
session.gc_probability = 0
次に、計画されたタスクで定期的に実行します。
$handler->gc(1440); // たとえば、それぞれ24数分に一度掃除します
データベースに加えて、セッションストレージとGCメカニズムは、Redis、Memcachedなどに基づいて構築することもできます。たとえば、Redisを使用する場合、複雑なGC()メソッドを手動で実装せずにTTLメカニズムで自動的に期限切れになる可能性があります。
$redis->setex("sess_$id", $max_lifetime, $data);
その他の例については、 https://m66.net/examples/sessionhandlerを参照してください。
sessionhandlerinterface :: gc()メソッドを実装することにより、PHP開発者はセッションガベージクリーニングを完全に制御できます。これは、高性能でスケーラブルなWebアプリケーションを構築するために重要です。データベース、Redis、またはその他のミドルウェアを使用するかどうかにかかわらず、 GC()およびシステムレベルのスケジューリングツールの合理的な使用は、セッション管理の効率とシステムメンテナビリティを大幅に改善できます。
関連タグ:
SessionHandlerInterface