首頁>技術>

引言

前一期我們介紹了儲存使用者會話資料到伺服器,並通過框架提供的Session類 進行資料讀寫操作的方法。

但是有些資料,如資料庫集合,API介面等等,對於全域性的使用者來說是無差別的, 這時候我們需要全域性快取以便提供給所有的使用者使用。

本期就來說說Cache快取。

程式碼時間

laravel在設計上做了很巧妙的構思,將快取相關的類,設計得有插接件的感覺。 所以,你看到Session Cache Cookie 這些快取資料類,基本上除了底層的驅動, 資料結構,過期特性等等,都集成了系統陣列類Arr的操作方法。所以上述三種快取在 操作方法上有很多相同之處。

cache快取的配置檔案在 config/cache.php 內,支援的驅動預設是 file, 也就是文字檔案儲存。還有很多內建可選項:

file 檔案儲存apc php內建快取array 記憶體變數database 資料庫memcached / redis 記憶體資料庫dynamodb aws記憶體資料庫

其中array驅動,是把資料直接存在變數內,放在伺服器記憶體中,一次請求結束,或者php-fpm 閒置超時釋放,就會登出掉。其他都提供了持久化的方案。

當然了,Cache快取提供的資料型別就多了去了,根據驅動的不同,支援的儲存結構也不相同。 比如檔案類,只能是陣列,連結串列,鍵值。而redis資料庫則可以儲存集合。這在使用的時候, 需要格外留意。

根據鍵名獲取一個快取值操作方法如下:

$users = Cache::get('users');

上面的程式碼使用了系統啟動時註冊的全域性Cache門面方法,我們也可以從容器內獲取一個Cache例項, 比如在路由內使用依賴注入的方式例項化:

Route::get('users', function (Illuminate\\Contracts\\Cache\\Repository $cache) {    return $cache->get('users');});

laravel也為我們提供了極為便捷的助手函式 cache() 直接操作快取。因為封裝得過於精巧, 所以助手函式內定然是進行了大多數的情況判斷。我們對原始碼稍作解析,以便明白其處理方法。

$arguments = func_get_args();if (empty($arguments)) {    return app('cache');}

如果助手函式沒有傳入任何引數,比如這樣:

$users = cache();

那就使用應用容器例項化一個 Cache::class 類。可以用於後續的鏈式方法呼叫。 接著看原始碼:

if (is_string($arguments[0])) {    return app('cache')->get(...$arguments);}

判斷第一個位置引數,如果是字串,那麼推斷使用者就是要獲取的鍵名。那就例項化Cache類並呼叫get方法獲取快取值。

if (! is_array($arguments[0])) {    throw new Exception(        'When setting a value in the cache, you must pass an array of key / value pairs.'   );}

為了排除其他所有情況,此處使用了NOT 邏輯判斷。 也就是說,助手函式cache()除了接收字串和陣列,其他一概不處理。

接下來,如果傳入的是陣列,程式的處理方法:

return app('cache')->put(key($arguments[0]), reset($arguments[0]), $arguments[1] ?? null);

如果是陣列,系統推斷使用者是要通過助手函式設定快取值了。 那就就用第一個位置引數陣列的鍵作為快取的鍵名,陣列的第一個值作為快取的值。 同時檢視是否有第二個位置引數,將其作為expired過期時間處理。沒有的,則預設為null,永不過期。

$users = cache('key', 'default value');$users = cache()->get('key', 'default value');

上面是根據鍵名獲取快取值。正好命中了原始碼中前兩種情況。

$users = cache(['key' => 'value'], $minutes);$users = cache()->put('key', 'value', $minutes);

寫入資料也很簡單,傳入陣列和過期時間,或者例項化之後直接呼叫put方法。

laravel日期時間處理預設使用Carbon類庫,所以快取也用到了該庫, 並且把用法發揮到極致了。

比如我們可能想動態地設定過期時間,不計算時長,能不能設定為 到某個時間點結束 ? 自然是可以的。這樣來寫程式碼:

cache()->put('key', 'value', Carbon::now()->addDay());

put方法第三個引數傳入一個Carbon物件,就是預設快取到指定的時間點。 至於時長,laravel幫你算好了。我們只關心這個到期時間點,程式碼可讀性明顯增強了許多。

其他方法不一一介紹了,特別說一下有個需求,比如說程式碼中,我們先查詢快取資料,如果沒有就去程式上下文獲取。 如果存在,就直接返回快取資料。

這個邏輯用的很多,laravel提供了一個remember語法糖,讓你解決這個操作步驟:

$users = cache()->remember('users', 120, function () {    return User::all();});
寫在最後

本文通過對快取助手函式cache()的分析,為大家介紹了Cache類傳參的一些關鍵點。 特別是remember方法,在上下文邏輯不復雜的處理中,可有效減少程式碼量,非常直觀。

Happy coding :-)

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • LeakCanary原始碼及ContentProvider優化