天天看點

3分鐘短文:說說Laravel頁面會話之間的資料儲存Session用法

引言

我們知HTTP請求是沒有狀态的,兩個請求之間沒有直接的關聯關系。但大多數情況下,

我們需要保持使用者的會話間資料的連續性,這時,為了資料安全起見,

有必要在伺服器上臨時存儲一些上下文資料了。

3分鐘短文:說說Laravel頁面會話之間的資料儲存Session用法

這就是 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 在門面 IlluminateSupportFacadesSession 内注冊的。

因為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 :-)

我是@程式員小助手,持續分享程式設計知識,歡迎關注。