0

ガベージコレクトがいつ実行されるかを正確に知りたいので、以下のテストスクリプトを作成しました。

<?php

ini_set('session.gc_maxlifetime',10);
ini_set('session.gc_probability',1);
ini_set('session.gc_divisor',1);

echo ini_get('session.gc_maxlifetime').'s ';
echo ini_get('session.gc_probability').'/';
echo ini_get('session.gc_divisor')."<br>";

session_start();
echo session_id();
if (isset($_SESSION['test']))
{
    echo "<br>";
    echo "session set";
}
$_SESSION['test'] = "works";
echo "<br>";
print_r($_SESSION);

?>

#1を試してください:最初に試してみると、次のようになります。

10s 1/1
e9isrrljuvdbr1c6vqndp1e4i7
Array ( [test] => works )

#2を試してください:10秒以上待ってから:

10s 1/1
e9isrrljuvdbr1c6vqndp1e4i7
session set
Array ( [test] => works )

#3を試してください:その後いつでも私は得ます:

10s 1/1
e9isrrljuvdbr1c6vqndp1e4i7
Array ( [test] => works )

ガベージコレクションが試行#2では開始されず、試行#3で開始されるのはなぜですか?

4

1 に答える 1

1

セッション データの PHP ガベージ コレクションは、最終的にデータを消去するように設計されており、データが消去されることを保証するものではありません。

セッションを開始すると、PHP は前回のリクエストからすでに保存されているセッション データを見つけようとします。これに失敗すると、セッションがまったく新しいものであると見なされ、ディスク上に空のセッション ファイルが作成されてロックされ、$_SESSION が空の配列として初期化されます。

スクリプトの最後、またはsession_write_close()が呼び出されると、$_SESSION の内容がこのファイルにシリアル化され、ロックが解除され、スクリプトが終了します。

その場合にのみ、ガベージ コレクションが一定の確率で開始されます (つまり、100 回のリクエストのうち 1 回だけがガベージ コレクションを開始します)。すべてのセッション ファイルの有効期限がスキャンされ、ファイルの最終変更時刻がsession.gc_maxlifetime設定よりも古い場合は削除されます。

実はsession.gc_maxlifetime表記が間違っています。session.gc_minlifetimeセッションデータは少なくともこの時間存続するため、実際にはそうです。

2 つ目: ガベージ コレクションは、データが新しく保存されるため、アクティブに使用しているセッションを破棄できません。

3 番目: ガベージ コレクションには、それをトリガーするための要求が必要です。バックグラウンドで自動化されたプロセスではありません。

ポイント 2 と 3 を組み合わせると、ガベージ コレクションによって、 より古い十分に古い OTHER セッションのみが消去されますsession.gc_maxlifetime。それをテストするには、少なくとも 2 つのセッションが必要です。1 つは期限切れになり、もう 1 つはガベージ コレクションの実行をトリガーします。

したがって、次のようになります。2 つのブラウザを用意し、両方でセッション ページにアクセスします。session.gc_maxlifetime1 つのブラウザーでページを定期的にリロードし、2 番目のブラウザーで数秒以上待ちます。その後、2 番目のブラウザをリロードしてください。セッションは終了するはずです。

于 2012-10-24T07:05:12.853 に答える