ここに事があります。私の同僚は、私たちが使用しているフレームワークのセッション処理を上書きしようとしています。このフレームワークはデフォルトでPHP独自のネイティブセッション処理を使用していますが、現在はリクエスト間にデータベースレイヤーを実装しようとしています。ここには真の挑戦があります:セッションが書かれる前にPHPがシャットダウン機能を呼び出すのはなぜですか?
問題は、セッションがもう書き込まれるまでにデータベースオブジェクトが利用できないということですが、セッションからデータを読み込むときなど、他の機能にも使用できます。これは野生の行動です。
register_shutdown_function('exithandler');
session_set_save_handler(
'sess_open',
'sess_close',
'sess_read',
'sess_write',
'sess_destroy',
'sess_gc'
);
これらの機能のそれぞれは、ログファイルに1行を書き込んで、機能の名前で追跡することもできます。これは、関数が呼び出されるたびに実行されます。ここで2つのURLが要求されます。最初はセッションが実際に書き込まれる場所(セッションに新しいデータ)とセッションのデータがちょうどチェックされた場所(書き込まれない場所)です。ここにパズルがあります:
/login/
sess_open
sess_read
exithandler
sess_write
sess_close
/account/
sess_open
sess_read
sess_write
sess_close
exithandler
なぜこの動作が異なるのですか?同じメソッドが実際に呼び出されたにもかかわらず、データがセッションに格納される前に出口ハンドラが呼び出されて、なぜ通常のページで同じでないのはなぜですか?
exithandlerが呼び出された後に私たちのクラスがもう使用できないという問題があります。私は、PHPのガベージコレクタがすべてのクラスで__destruct()メソッドを呼び出したと仮定しています。これはちょうど悪いことです。
PHPがこのように動作する理由は誰でも知っていますか?
使用しているPHPのバージョンは? –
私はこれをPHP 5.4でテストしましたが、セッションデータの読み込みと書き込みの両方のタイプの要求に対して、最初の操作順序しか再現できません。 – nickb
PHPのいくつかのバージョンでは、 'session_set_save_handler()'を呼び出す前に行を追加する必要があるという共通の問題があります。最初に 'register_shutdown_function( 'session_write_close')'を使って不安定な動作を修正するかどうかを確認してください。 –