首頁>技術>

引言

我們知HTTP請求是沒有狀態的,兩個請求之間沒有直接的關聯關係。但大多數情況下, 我們需要保持使用者的會話間資料的連續性,這時,為了資料安全起見, 有必要在伺服器上臨時儲存一些上下文資料了。

這就是 session 設計的目的。

程式碼時間

在laravel中可以使用系統提供的Session類方便地操作會話資料,而且其儲存介質也是抽象出來的, 可以無縫銜接,只是驅動更換一下罷了。

框架內Session支援的驅動型別如下:

file 儲存在 storage/framework/sessions 目錄cookie 儲存在安全加密的 cookie 中database 建立專門的表,儲存在資料庫內memcached, redis 儲存在這些記憶體資料庫內array 每次請求有效,用完即焚,適合測試使用

session 資料以簡單的鍵值方式儲存,所以讀取某個鍵名的值,只需

session()->get('user_id');

其中函式 session() 是laravel系統提供的助手函式。我們看一下原始碼的定義:

function session($key = null, $default = null){    if (is_null($key)) {        return app('session');   }    if (is_array($key)) {        return app('session')->put($key);   }​    return app('session')->get($key, $default);}

如果鍵名為空,返回一個 app('session'),使用應用容器例項化一個Session物件。 其中,別名 session 在門面 Illuminate\\Support\\Facades\\Session 內註冊的。

因為session是在頁面請求之間的保持,所以Request物件也提供了session的方法。 在 FormRequestServiceProvider 內註冊請求體時呼叫初始化方法:

$request = FormRequest::createFrom($app['request'], $request);

其中 createFrom 方法做了session資料寫入:

if ($session = $from->getSession()) {    $request->setLaravelSession($session);}

所以有了以上基礎,我們就可以這樣鏈式呼叫獲取一個請求所對應的session值:

Route::get('dashboard', function (Request $request) {    $request->session()->get('user_id');});

或者使用依賴注入的方式,直接從儲存中讀取資料:

Route::get('dashboard', function (Illuminate\\Session\\Store $session) {    return $session->get('user_id');});

為了發揮PHP靈活的特點,助手函式session也提供了完整無二的類似 request cache等等的操作方式讀寫資料。 比如讀取某個鍵的值:

$value = session()->get('key');$value = session('key');

還有寫入值:

session()->put('key', 'value');session(['key', 'value']);
使用技巧

下面說一些在儲存session資料上的用法,以及框架提供的類的方法。 比如直接根據鍵名獲取值:

$points = session()->get('points');

如果鍵名不存在則使用預設值:

$points = session()->get('points', 0);

來看一下 get 方法的定義,我們會學到更為靈活的用法:

public function get($key, $default = null){    return Arr::get($this->attributes, $key, $default);}

注意在變數型別提示上,$default 是 mixed 泛型。再接著看 Arr::get() 方法的使用:

if (! static::accessible($array)) {    return value($default);}

如果傳入的$this->attributes 是陣列,那麼使用 value() 助手函式取值。 看一下該助手函式的定義:

function value($value){    return $value instanceof Closure ? $value() : $value;}

我們發現,如果傳入的是一個匿名函式,那麼直接進行了呼叫,並返回執行後的值。這樣, 我們就可以深度改造一下上面的 session()->get() 方法的第二個 default ,將其傳入一個匿名函式, 用於處理獲取預設值的邏輯。

看這樣一段程式碼:

$points = session()->get('points', function () {    return (new PointGetterService)->getPoints();});

是不是瞬間又有新知識了 :-) 有了匿名函式的支援,這個預設值你可以玩出花兒來了~~

寫在最後

本文介紹了laravel處理請求間資料的保持方式:session。比介紹了在程式內獲取session的方式, 並深入原始碼,探索了Session::get() 方法的高階用法。

Happy coding :-)

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 微前端在58商業的探索實踐