開発者は、セッションのライフサイクルが設定されていても、古いセッションデータが長い間存在することに気付くかもしれません。これは通常、 session_gc()がすべてのリクエストを実行しないためです。
原因分析:
PHPのセッションリサイクルメカニズムは確率に基づいてトリガーされ、デフォルトの構成は次のとおりです。
session.gc_probability = 1
session.gc_divisor = 100
これは、平均して、100個に100個のリクエストのうち1個のみがGC操作をトリガーすることを意味します。
解決:
GCトリガーの確率を増やすか、手動でsession_gc()を呼び出すことにより、クリーンアップを強制的に整理できます。
ini_set('session.gc_probability', 100);
ini_set('session.gc_divisor', 100);
または適切なタイミングで使用します。
session_start();
session_gc();
問題の説明:
GCは、カスタムセッション保存メカニズム(データベース、Redisなど)を使用する場合、効果がないようです。
原因分析:
GC()メソッドがCustom SessionHandlerクラスで正しく実装されていない場合、PHPがsession_gc()を呼び出すと、データは実際にクリーニングされません。
解決:
sessionhandlerinterfaceのgc()メソッドが実装されていることを確認してください。たとえば、MySQLを使用してセッションを保存する場合、次のように実装できます。
class MySessionHandler implements SessionHandlerInterface {
// ...
public function gc($max_lifetime) {
$stmt = $this->pdo->prepare("DELETE FROM sessions WHERE last_access < :time");
$stmt->execute([':time' => time() - $max_lifetime]);
return true;
}
}
次に、登録します:
$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();
問題の説明:
session_gc()が呼び出されたとしても、古いセッションファイルはまだ削除されていません。
原因分析:
これは、 session.save_pathが間違ったディレクトリまたは不十分な権限を指しているためかもしれません。
解決:
正しい保存パスが設定されていること、およびPHPプロセスに読み書き許可があることを確認してください。
ini_set('session.save_path', '/var/lib/php/sessions');
フォルダー許可を確認してください:
sudo chown -R www-data:www-data /var/lib/php/sessions
sudo chmod 700 /var/lib/php/sessions
問題の説明:
CLIモード(タイミングスクリプトなど)でSESSION_GC()を呼び出しても効果がないか、エラーが報告されています。
原因分析:
CLI環境は、正しいセッションの構成(Save_Pathが空)を初期化したり、呼び出しが呼び出される前に初期化されたりしない場合があります。
解決:
session_gc()を呼び出す前に、必ず環境を明示的に構成してください。
ini_set('session.save_handler', 'files');
ini_set('session.save_path', '/var/lib/php/sessions');
session_gc();
問題の説明:
一部のWebサイトが長い間実行された後、多数の.sessファイルが/TMPディレクトリに保存され、多くのディスクスペースを占有します。
原因分析:
効果的なGCが長い間実行されていない場合、またはGC頻度が低すぎると、履歴セッションのデータがクリーニングされません。
解決:
別のスケジュールされたタスクスクリプトを設定し、定期的にsession_gc()を呼び出すことをお勧めします。たとえば、1時間に1回実行してください。
<?php
ini_set('session.save_path', '/var/lib/php/sessions');
session_gc();
Linux Cronタスクと組み合わせて:
0 * * * * /usr/bin/php /var/www/html/session_gc.php
問題の説明:
ロードバランスまたは逆プロキシ環境では、さまざまなノードがセッションデータを同期させないため、一貫性のないGCクリーニングが発生します。
解決:
Redisやデータベースなどの集中セッションストレージを使用して、GCポリシーを統合することをお勧めします。
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://gitbox.net:6379');
Redisスキームでは、Redisの有効期限メカニズムは定期的にクリーニングするか、Redisを使用して自動的に管理する必要があります。