36

session.gc_maxlifetimeとの実際の違いは何session_cache_expire()ですか?

ユーザー セッションが 15 分間非アクティブになった後 (最初に開かれてから 15 分間ではなく)、無効になるようにしたいとします。これらのうちどれが私を助けてくれるでしょうか?

session_set_cookie_params()また、ユーザーの Cookie が一定時間で期限切れになるように設定できることも知っています。ただし、Cookie の有効期限とサーバー側での実際のセッションの有効期限は同じではありません。これは、Cookie の有効期限が切れたときにセッションも削除しますか?

私が持っている別の解決策は、すべてのリクエストで簡単 $_SESSION['last_time'] = time() で、セッションを現在の時刻と比較し、それに基づいてセッションを削除することです。ただし、これを処理するための「組み込み」メカニズムがもっとあることを望んでいました。

ありがとう。

4

4 に答える 4

59

php.ini サーバー設定がどのようにセッションを期限切れにするかについて、適切な回答を探すのに時間を費やしました。多くの情報を見つけましたが、設定がそのように機能する理由を理解するのに時間がかかりました. あなたが私のような人なら、これはあなたに役立つかもしれません:

セッションは Cookie (クライアントの PC 上のファイル) として保存されるか、サーバー側のファイルとしてサーバー上に保存されます。どちらの方法にも長所と短所があります。

サーバーに保存されたセッションには、3 つの変数が使用されます。

session.gc_probability session.gc_divisor session.gc_maxlifetime

(session.gc_probability/session.gc_divisor) は、ガベージ コレクション ルーチンが実行される確率を生成します。ガベージ コレクターが実行されると、少なくとも session.gc_maxlifetime の間アクセスされていないセッション ファイルがチェックされ、それらが削除されます。

これはすべてフォーラムの投稿でかなりよく説明されています (これは特に!) - しかし、次の質問が出てきます:

1.) その確率はどのように適用されますか? サーバーがサイコロを振るのはいつですか?

A: サーバー上のアクティブなセッション中に session_start() が呼び出されるたびに、サーバーはサイコロを振ります。これは、session.gc_probability = 1 および session.gc_divisor = 100 のデフォルトを使用している場合、session_start() が呼び出される 100 回ごとにガベージ コレクターが実行されることを意味します。

2.) ボリュームの少ないサーバーではどうなりますか?

A: session_start() が呼び出されると、最初にセッションが更新され、セッションの値が利用できるようになります。これにより、サーバー上のセッション ファイルの時刻が更新されます。その後、サイコロを振って、勝った場合 (100 分の 1 の確率)、ガベージ コレクターを呼び出します。次に、ガベージ コレクターはすべてのセッション ID ファイルをチェックし、削除できるファイルがあるかどうかを確認します。

つまり、サーバー上にあなたが 1 人しかいない場合、セッションが非アクティブになることはなく、設定を変更しても効果がないように見えます。session.gc_maxlifetime を 10 に変更し、session.gc_probability を 100 に変更したとします。これは、100% の確率でガベージ コレクターが実行され、過去 10 秒間アクセスされていないセッション ファイルがすべて消去されることを意味します。

サーバー上に自分しかいない場合、セッションは削除されません。あなたのセッションが非アクティブになるには、他のアクティブなセッションが少なくとも 1 つ実行されている必要があります。

したがって、基本的に、低ボリュームのサーバーまたは低ボリュームの時間では、ガベージ コレクターが実際に実行されてセッションが実際に削除されるまでに、session.gc_maxlifetime よりもはるかに長くなる可能性があります。そして、これがどのように機能するかを知らなければ、完全にランダムに見えるかもしれません.

3.) なぜ彼らは確率を使うのですか?

パフォーマンス。大容量のサーバーでは、session_start() のすべてのリクエストでガベージ コレクターを実行したくありません。サーバーを不必要に遅くします。そのため、サーバーのボリュームに応じて、ガベージ コレクターが実行される確率を増減させたい場合があります。

これがあなたのために物事を結びつけることを願っています。あなたが私のようで、session.gc_maxlifetime を試してみてうまくいかなかった場合 (誰の邪魔にもならないように開発サーバーで試したために)、この投稿で頭を悩ませずに済んだことを願っています。

幸運を!

于 2009-10-01T18:20:01.613 に答える
41

session_startが呼び出されるたびに、セッションファイルのタイムスタンプ(存在する場合)が更新されます。これは、session.gc_maxlifetimeを超えたかどうかを計算するために使用されます。

さらに重要なことに、session.gc_maxlifetime時間を超えた後に期限切れになるセッションに依存することはできません。

PHPは、現在のセッションがロードされた後、期限切れのセッションでガベージコレクションを実行し、 session.gc_probabilitysession.gc_divisorを使用して、ガベージコレクションが実行される確率を計算します。デフォルトでは、1%の確率です。

訪問者の数が少ない場合、非アクティブなユーザーが、期限切れになって削除されたはずのセッションにアクセスする可能性があります。これが重要な場合は、セッションにタイムスタンプを保存し、ユーザーが非アクティブになっているログを計算する必要があります。

この例では、 session_startを置き換え、タイムアウトを強制します。

function my_session_start($timeout = 1440) {
    ini_set('session.gc_maxlifetime', $timeout);
    session_start();

    if (isset($_SESSION['timeout_idle']) && $_SESSION['timeout_idle'] < time()) {
        session_destroy();
        session_start();
        session_regenerate_id();
        $_SESSION = array();
    }

    $_SESSION['timeout_idle'] = time() + $timeout;
}
于 2009-08-06T01:46:55.437 に答える
6

session.gc_maxlifetimeは、セッション ファイルが最後に変更された時刻に基づいています。そのため、セッション ファイルが変更されるか、別のページで session_start() が呼び出されるたびに、gc_maxlifetime へのカウントダウンが新たに開始され、ユーザーは「ログイン」したままになります。これが探している値です。これは、php ファイルの ini_set() を介して変更するか、アクセスできる場合は php.ini を編集できます。

session_cache_expire()は、HTTP の「Expires」ヘッダーのみを制御します。このヘッダーは、ダウンロードされたページ コンテンツがユーザーのブラウザ キャッシュに保持される期間を制御します。

于 2009-08-06T01:23:04.863 に答える