Laravel Session 遇到的坑
這兩天遇到了一個(gè)很奇怪的問題,更新session ,session的值不變。經(jīng)過一番追查,終于找到問題,并搞明白了原理。寫這篇博客記錄下。
框架版本
Laravel 5.4
問題
先來描述下問題,我在我們項(xiàng)目基礎(chǔ)的Middleware中,加入session操作,存入了一個(gè)值,再在Controller中取出使用,大致代碼如下:
// Middleware public function handle($request, Closure $next) {$id = Redis::get('id');session(['id' => $id]);return $next($request); }// Controller public function index() {$id = session('id');return ['id' => $id]; }假設(shè)reids中的id是1,這一次訪問index這個(gè)action,返回的是1,當(dāng)你將redis中id的值改成2時(shí),在訪問,發(fā)現(xiàn)返回的還是1,而且之后的訪問也都是1。這里說明一下session使用的是redis 。
解決問題
看到這樣神奇的結(jié)果,百思不得其解。于是打開Xdebug,開始調(diào)試。經(jīng)過多次調(diào)試,發(fā)現(xiàn)在執(zhí)行完
\Illuminate\Session\Middleware\StartSession這個(gè)Middleware后,session里面的值就變回1了,在之前都是2。然后想到會(huì)不會(huì)我們的Middleware在StartSession之前執(zhí)行造成的,將我們的Middleware移到StartSession之后,發(fā)現(xiàn)果然可以了,app/Http/Kernel.php中的代碼如下:
其中的OurMiddleware是我們自己寫的Middleware,之前是放在最上面的,$next($request)之前的代碼的執(zhí)行順序是從上到下的,如果OurMiddleware中有些內(nèi)容是必須在最開始的,可以考慮分成兩個(gè)Middleware。
理解原理
雖然解決了問題,但還是不知道其原理究竟是怎樣的,帶著這樣的疑問我繼續(xù)查看源碼,最終找到了相應(yīng)的內(nèi)容。
session不是實(shí)時(shí)落地的,也就是說當(dāng)你調(diào)用session(['id' => $id])時(shí),id并沒有被真正存入redis中,而是緩存在 \Illuminate\Session\Store單例的attributes屬性中,可以查看其put方法,代碼如下:
foreach ($key as $arrayKey => $arrayValue) {Arr::set($this->attributes, $arrayKey, $arrayValue);}
```php
public function put($key, $value = null)
{
if (! is_array($key)) {
$key = [$key => $value];
}}
```\Illuminate\Session\Middleware\StartSession在執(zhí)行時(shí),回自動(dòng)加載redis中已經(jīng)實(shí)例化的數(shù)據(jù),并覆蓋\Illuminate\Session\Store單例中的attributes屬性,所以這就導(dǎo)致我們一直取到的都是redis中的session數(shù)據(jù)。加載覆蓋的代碼如下:
protected function loadSession() {$this->attributes = array_merge($this->attributes, $this->readFromHandler()); } protected function readFromHandler() {if ($data = $this->handler->read($this->getId())) {$data = @unserialize($this->prepareForUnserialize($data));if ($data !== false && ! is_null($data) && is_array($data)) {return $data;}}return []; }
其中的readFromHandler方法就是獲取redis中的session數(shù)據(jù)。
后記
其實(shí)這不是Laravel session的坑,是我自己踩坑,原諒我是個(gè)標(biāo)題黨
轉(zhuǎn)載于:https://www.cnblogs.com/CraryPrimitiveMan/p/6654674.html
總結(jié)
以上是生活随笔為你收集整理的Laravel Session 遇到的坑的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 你需要知道的vue2 jsx rende
- 下一篇: 做梦梦到猪死了是什么意思