タイムアウトまたはブラウザのクローズによってセッションが破壊されたときに関数を実行する方法はありますか?
はい、しかしそれはあなたが想像するようには機能しないかもしれません。を使用して独自のカスタムセッションハンドラーを定義できます。定義のsession_set_save_handler
一部は、destroy
およびgc
コールバック関数を提供することです。これらの2つは、セッションが明示的に破棄されたときと、セッションが期限切れになったために破棄されたときに呼び出されるため、要求どおりに実行されます。
ただし、タイムアウトによるセッションの期限切れは、時計仕掛けの精度では発生しません。期限切れのセッションが実際に「ガベージコレクション」されるまでには、かなりの時間がかかる場合があります。さらに、ガベージコレクションは確率的にトリガーされるため、理論的には、期限切れのセッションがガベージコレクションされない可能性があります。
それは官能的ですか?共有サーバーでは数百の同時SQLクエリが問題になり、これを軽減するために$_SESSIONをバッファーとして使用するというアイデアがあります。
私は実際にはいくつかの理由でこれをしませんでした:
- 時期尚早の最適化(測定する前に、それが「より良い」と単に想定しないでください)。
- セッションがガベージコレクションされることはありません。これが起こらなくても、いつ収集されるかを制御することはできません。これは問題になる可能性があります。
- プレーヤーの進行状況を含め、セッションに含まれるすべてのもの(サーバーの再起動など)が失われる可能性があります。プレイヤーは進歩を失うのが好きではありません。
- 同じユーザーの同時セッションは不可能です(「保存されたデータ」が優先され、データベースに保持されたままになりますか?)。
代替案はどうですか?
ええと、私たちはel cheapo共有ホスティングについて話しているので、あなたは間違いなくサーバーを制御するつもりはないので、PHP拡張機能(memcachedなど)を含むものはすべて条件付きです。データベース側のキャッシュも飛ぶことはありません。さらに、サーバーの負荷は制御外の変数の影響を受けるため、キャパシティプランニングを実際に行うことはできません。
いずれにせよ、データベース自体が最適に構造化されていることと、データベースへの負荷を最小限に抑える方法でコードが記述されていることを確認することから始めます(エディターに入力するだけでパフォーマンスが向上します)。
その後、読み取り専用キャッシュを導入できます。通常、表示する必要があるものの、変更するつもりのないものがたくさんあります。「ほとんどない」データの場合、必要なときにいつでも無効にするセッションキャッシュは、簡単で非常に効果的な改善になる可能性があります(無効化に関して誤検知が発生する可能性もありますが、その数が多すぎない限り、物事の壮大な計画)。
最後に、1回のリクエストで同じデータをデータベースから2回プルする必要がある場合は、リクエストごとのキャッシュを(変数で)追加できます。