PHPのsessionファイルの生成場所、中身、有効期限など
PHPでセッションを開始すると$_SESSIONに値を出し入れできますが実態はsessionファイルに物理的に書き込まれています。*1
中身見たことなかったのでちょっと調べました。
sessionファイルの場所
生成場所の優先順位
sess_v4vqefhjjllja1bqsabekihpc4
みたいな感じでsess_xxxxxxxxxxxxxx
という名前のファイル名で保存されます。
sessionファイルの中身
試しにこれを実行すると
<?php session_start(); $_SESSION['hoge'] = 'hoge'; $_SESSION['huga'] = 'huga';
自分の環境だと/tmp/sess_v4vqefhjjllja1bqsabekihpc4
が生成されました。中身をみると
cat /tmp/sess_v4vqefhjjllja1bqsabekihpc4 // 結果 hoge|s:4:"hoge";huga|s:4:"huga";
ぱっと見配列をserialize()
したものっぽいですが微妙に違います。
session_encode
という関数を使ってエンコードしているようです。
PHP: session_encode - Manual
デフォルトのアンシリアライズの方法は PHP が内部的に実装しているものであり、 unserialize() とは違います。 シリアライズの方法は、session.serialize_handler で設定できます。
phpinfoを確認するとsession.serialize_handlerにはphp
と設定されていました。これがデフォルト値です。試しにphp_serialize
に変えてphpを再起動してsessionファイルを確認してみると
cat /tmp/sess_v4vqefhjjllja1bqsabekihpc4 // 結果 a:2:{s:4:"hoge";s:4:"hoge";s:4:"huga";s:4:"huga";}
とまぁおなじみのシリアライズされた文字列になりました。ハンドラがデフォルトのphp
だと$_SESSIONの中で数値のインデックスや特殊文字 (| や !) を含む文字列のインデックスが使えません。
sessionファイル名とセッションID
リクエストヘッダーを見るとv4vqefhjjllja1bqsabekihpc4
というセッションIDを送っています。
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch Accept-Language:ja,en-US;q=0.8,en;q=0.6,de;q=0.4,fr;q=0.2,ko;q=0.2 Cache-Control:max-age=0 Connection:keep-alive Cookie:PHPSESSID=v4vqefhjjllja1bqsabekihpc4 // ←! Host:local.example.com Upgrade-Insecure-Requests:1
クライアントから送信されたセッションIDとsessionファイルの関連付けをどうやっているのかというとそのままセッションIDに接頭辞としてsess_
をつけているだけだけでした。セッションIDをそのままファイル名に使っているというのはなにやら不安な気持ちになりますね。
session_regenerate_id ()
を実行するとセッションIDが新しく変わるので新しいsess_xxxxxx
が生成され、クライアントに新しいセッションIDを返します。
有効期限
セッションスタート時にgcが走ります。
sessionファイルのうち生成からsession.gc_maxlifetime
秒経っているファイルが対象で、session.gc_divisor
分のsession.gc_probability
の確率で削除が実行されます。
*1:デフォルトでは。