session_set_save_handler()でカスタムセッションハンドラ設定したらFatal error: Class not found
複数のwebサーバーでセッション情報共有するのにmemcached使うためにカスタムセッションハンドラ設定したら
ばっちり定義してるはずのクラスがなかったことになっててびびった話。
問題のあったスクリプト
<?php class Hoge {} class MySessionHandler { public function open($save_path, $session_name){ /*処理*/ } public function close(){ /*処理*/ } public function read($id){ /*処理*/ } public function write($id, $sess_data){ $hoge = new Hoge(); } public function destroy($id){ /*処理*/ } public function gc($maxlifetime){ /*処理*/ } } $s = new MySessionHandler(); session_set_save_handler(array($s,'open'), array($s,'close'), array($s,'read'), array($s,'write'), array($s,'destroy'), array($s,'gc')); session_start(); $_SESSION['fuga'] = 'abc';
↓ごらんの有様だよ!
Fatal error: Class 'Hoge' not found in /xxx/xxx/sessiontest.php on line 8
Hogeってすぐそこに定義してるじゃん! Σ(・ω・;)
エラーの原因
どこでエラーになってるか
session_set_save_handler()の引数(callback $write)で指定した処理の実行時にエラーが起きています。
解決方法
デストラクタでsession_write_close()
オブジェクト破棄の前にwriteハンドラコールすればよい。
http://php.mirror.camelnetwork.com/manual/ja/function.session-set-save-handler.php#refsect1-function.session-set-save-handler-notes
この「ニワトリが先かタマゴが先か」の問題を解決するために、 デストラクタから session_write_close() を コールすることが可能です。
こんな感じでOK
<?php class MySessionHandler { // 省略 // // ↓追加 public function __destruct(){ session_write_close(); } }