人気ブログランキングへ

2009年03月23日

PHP のセッション寿命の設定

PHP のセッションの寿命 (有効期限) に関する仕組みはややわかりにくく、いつもすぐに忘れてしまうのでメモしておく。

以下、PHP がセッションデータをどのように格納し、ブラウザからのリクエストによってどのようにデータを返すか、仕組みを理解していることが前提。

(1) セッションの保持方法の選択

ブラウザ側でのセッションIDの保持のしかたによってやや事情が異なる。
ブラウザがセッションを維持する方法は、セッションIDをパラメータ渡しする方法と、ブラウザの Cookie に持つ方法の2つがある。

セッションIDをブラウザの Cookie として持つには、たとえば以下のように設定する。

ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.use_trans_sid', 0);


1つめはもちろん必須、2つめはセキュリティ強化のために推奨。
3つめの設定は、session.use_cookies を 1 に設定した時点で意味をなさなくなるが、とりあえず設定してみた。

携帯電話などは、Cookie を利用できないことがほとんどだと思うので、セッションIDをパラメータ渡しすることになる。
そのためには、たとえば以下のように設定する。

ini_set('session.use_cookies', 0);
ini_set('session.use_only_cookies', 0);
ini_set('session.use_trans_sid', 1);


1つめは必須。
3つめを設定しておくとリンクやフォームに自動的にセッションIDを追加してくれて楽ちんである。
2つめの設定はおまけ。


以下、それぞれの場合についてセッション寿命の設定方法を説明する。
設定はもちろん、session_start() を実行する前に済ませておく必要がある。

(2) セッション寿命の設定 (セッションIDをパラメータ渡しする場合)

サーバーで保持しているセッションデータは、古くなると「ガベージコレクタ」(Garbage Collector) に削除される。

ガベージコレクタに関わる設定値は3つある。

session.gc_probability (デフォルト値: 1)
session.gc_divisor (デフォルト値: 100)
session.gc_maxlifetime (デフォルト値: 1440)


PHP は、ガベージコレクション用のプロセスを別に実行させているわけではなく、セッションの開始時に実行するようになっている。
しかも、セッションが開始されるたびに必ず実行されるわけではなく、
session.gc_probability / session.gc_divisor の確率で実行される。
つまり、session.gc_probability を大きく (session.gc_divisor を小さく) するほど、ガベージコレクションの実行頻度は高くなる。

また、ガベージコレクタが実行された場合「ゴミ」とみなされるのは、session.gc_maxlifetime 秒以上経過したセッションデータである。

以上のことから言えるのは、セッション寿命は session.gc_maxlifetime で指定できるが、session.gc_probability / session.gc_divisor の値が小さく、セッションの開始頻度が低ければ延命される可能性も高くなる、ということ。

もし、古いセッションデータの息の根を確実に止めたければ、session.gc_probability / session.gc_divisor が 1 になるように設定する。

つまりたとえば、

ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
ini_set('session.gc_maxlifetime', 2 * 60 * 60);


とすれば、セッションデータは2時間経過後にきっちり片付けられる。

ただし、セッションの開始頻度が高く、セッション寿命が長いシステムの場合はパフォーマンスに影響するかもしれない。

(3) セッション寿命の設定 (セッションIDをクッキーに保持する場合)

ガベージコレクタを用いたセッション寿命の設定は (2) と同じだが、それに加えてブラウザのクッキー寿命によってもセッション寿命を調整できる。

セッションのクッキーの設定は session_set_cookie_params() 関数で行える。
タグ:PHP
posted by K/I at 00:32 | 東京 ☔ | Comment(0) | TrackBack(0) | 技術メモ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック