2015年10月23日 星期五

Laravel的Session不等於PHP Native Session

在Laravel內我們可能寫了以下的程式碼 ```php get('/session', function () { session_start(); session()->put('foo', 'bar'); $_SESSION['foo'] = 'bar'; header('location: '.url('/session/display')); exit; }); get('/session/display', function () { session_start(); ob_start(); dump(session()->get('foo')); dump($_SESSION['foo']); $content = ob_get_clean(); // output null, 'bar' return $content; }); ``` 會發現輸出結果完全不如我們所預期,為什麼會這樣呢?我們就好好的來做個探討吧... ## 原因出在Laravel的Session根本不是用PHP Native Session 在遇到這個狀況後,於是就去查了一下Laravel Session倒底是怎麼一回事,發現Laravel的程式碼內根本沒有執行session_start()啊 ## Laravel Session倒底是怎麼運作的 追了一下Laravel的原始碼,發現它是利用[Illuminate\Session\Middleware\StartSession](https://github.com/illuminate/session/blob/master/Middleware/StartSession.php)來進行php session模擬的, 在Laravel執行的最後階段在將存在記憶體內的資料進行實體寫入, 所以只要在我們只要在程式內任意一個地方執行了php的exit, die, header('location: xxx'); 那Session就不會被存入檔案內,自然在下一次連線也就取不到值了 ## 有沒有解決方案 有,當然有,只要輸入 ```php get('/session', function () { session_start(); session()->put('foo', 'bar'); $_SESSION['foo'] = 'bar'; session()->save(); // 手動寫入 dump($_SESSION['foo']); $content = ob_get_clean(); // output 'bar', 'bar' return $content; }); ``` ## 後記 為什麼會有這一篇的出現,因為我們可能會用很多其它已經寫好的library,但它們就是有用到session_start();外加header, die, exit等等指令啊,所以記錄一下來提醒自己囉