在 Laravel 中能夠使用 Session 的 get, put, pull, set, has, flash 等方法進行操做,如:Session::put([‘domain’=>’tanteng.me’, ‘host’=>’aliyun’]),就能夠設置兩個 session 值,看看 put 方法:php
代碼位於vendor/laravel/framework/src/Illuminate/Session/Store.phpPHPlaravel
/**
* Put a key / value pair or array of key / value pairs in the session.
*
* @param string|array $key
* @param mixed $value
* @return void
*/
public function put($key, $value = null)
{
if (! is_array($key)) {
$key = [$key => $value];
}瀏覽器
foreach ($key as $arrayKey => $arrayValue) {
$this->set($arrayKey, $arrayValue);
}
}session
代碼位於 vendor/laravel/framework/src/Illuminate/Session/Store.phpdom
它實際上經過 set 方法設置 session 值,set 方法:this
/**
* {@inheritdoc}
*/
public function set($name, $value)
{
Arr::set($this->attributes, $name, $value);
}
可見 set 方法僅僅是將值保存在 Store 這個類的屬性 attributes 中,也就是你多個保存 session 的操做都是將值保存在一個地方,此時並無真正設置,而是最後一次保存,保存 session 的方法是 Store 類的 save 方法。orm
其中 save 方法:中間件
/**
* {@inheritdoc}
*/
public function save()
{
$this->addBagDataToSession();
$this->ageFlashData();
$this->handler->write($this->getId(), $this->prepareForStorage(serialize($this->attributes)));
$this->started = false;
}
那麼在何處什麼時候調用 save 方法設置 session 值呢?get
Laravel 中間件 StartSessionstring
這裏就用到了 terminate 中間件,StartSession 這個中間件有個 terminate 方法,以下:
/**
* Perform any final actions for the request lifecycle.
*
* @param \Illuminate\Http\Request $request
* @param \Symfony\Component\HttpFoundation\Response $response
* @return void
*/
public function terminate($request, $response)
{
if ($this->sessionHandled && $this->sessionConfigured() && ! $this->usingCookieSessions()) {
$this->manager->driver()->save();
}
}
這裏只講講 StartSession 的 terminate 方法,其中 $this->manager->driver()->save() 這句便是調用前文講的 save 方法保存設置 session 值。
什麼是 Terminable 中間件
這裏引用其餘地方的一句話:
有時候中間件須要在 HTTP 的響應已經發送到瀏覽器以後去作點事。好比在 Laravel 裏包含的 session 這個中間件,它會在響應發送到瀏覽器以後,把 session 數據寫入到存儲裏面。要實現這個功能,你能夠把中間件定義成 terminable 。原來是在響應以後再作的事情,保存 session 的步驟是一次性在最後進行,這就是 Laravel Session 保存的機制,以及 terminate 中間件的用法。