3分鐘短文:說說Laravel通用緩存Cache的使用技巧

2020-12-15 程式設計師小助手

引言

前一期我們介紹了存儲用戶會話數據到伺服器,並通過框架提供的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 :-)

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

相關焦點

  • Django開發中使用Cache緩存提升10倍效率
    2分鐘,由此斷定肯定是Probius的問題了 又一次看了下這個子任務,發現任務的輸出日誌超過1w條,瞬間就知曉了其中的問題,經過簡單修改再次測試,原本執行24分鐘的任務執行時間縮短至3分鐘以內,效率提升相當明顯 究竟改了什麼擁有如此魔力呢?
  • Cache 和 Buffer 都是緩存,主要區別是什麼?
    為了說明這個問題,讓我將他們分開來說:read cache(讀緩存),read buffer(讀緩衝),write cache(寫緩存),write buffer(寫緩衝)。無論緩存還是緩衝,其實本質上解決的都是讀寫速度不匹配的問題,從這個角度,他們非常相似。首先討論讀緩存跟讀緩衝。
  • 創建Laravel自定義Helper輔助方法
    在之前我不太熱衷於創建自定義函數,隨著時間流轉,我開始越來越頻繁的使用它們。什麼是Laravel助手Laravel框架中的Helper方法其實就是普通的PHP函數,開發者可以從Laravel應用程式的任何部分來調用它,比如我們已經在該框架中使用內置的route(),url(),view(),dd()等方法一樣,不需要引用任何PHP文件或者聲明任何namespace來使用,如同奇蹟般,他們可以在你的應用程式中的任何部件中使用
  • 還在用 Guava Cache?它才是 Java 本地緩存之王!
    我們剛提到過LRU,常見的緩存淘汰算法還有FIFO,LFU:FIFO:先進先出,在這種淘汰算法中,先進入緩存的會先被淘汰,會導致命中率很低。LRU:最近最少使用算法,每次訪問數據都會將其放在我們的隊尾,如果需要淘汰數據,就只需要淘汰隊首即可。仍然有個問題,如果有個數據在 1 分鐘訪問了 1000次,再後 1 分鐘沒有訪問這個數據,但是有其他的數據訪問,就導致了我們這個熱點數據被淘汰。
  • 淺談Cache Memory
    在CPU內部存在一堆的通用寄存器(register)。如果CPU需要將一個變量(假設地址是A)加1,一般分為以下3個步驟:CPU 從主存中讀取地址A的數據到內部通用寄存器 x0(ARM64架構的通用寄存器之一)。通用寄存器 x0 加1。CPU 將通用寄存器 x0 的值寫入主存。
  • Cache的基本原理
    在CPU內部存在一堆的通用寄存器(register)。如果CPU需要將一個變量(假設地址是A)加1,一般分為以下3個步驟:CPU 從主存中讀取地址A的數據到內部通用寄存器 x0(ARM64架構的通用寄存器之一)。通用寄存器 x0 加1。CPU 將通用寄存器 x0 的值寫入主存。我們將這個過程可以表示如下:
  • 3分鐘短文:任命管理員,給Laravel普通用戶提權
    我們在users表內追加一個欄位 is_admin 用於標記用戶的管理員身份,使用命令創建遷移文件: 首先填充 up 方法用於遷移執行的邏輯: 如果遷移失敗,進行回滾使用的 down 方法: 完成編輯後保存,並執行遷移指令:
  • 3分鐘短文:Laravel ORM 模型用法綱要
    引言 前兩期為了說明laravel框架提供的資料庫操作能力,直接使用DB門面操作, 而沒有引入更為強大的eloquent orm功能。從本期開始,我們就分次把 eloquent的一些簡要知識點,為大家提煉演示一下。主要以代碼為主,配以簡要說明。
  • 聊一聊緩存雙一致問題以及spring cache
    很多人的用法是用Spring cache整合Redis然後在service層方法上用註解的方式做緩存,可以說非常的方便。然而,你確定真的用對緩存了嗎?在高並發下又怎樣保證緩存中的數據和資料庫中的數據一致呢?現在我們就來嘮一嘮。
  • 多圖詳解CPU Cache Memory
    在CPU內部存在一堆的通用寄存器(register)。如果CPU需要將一個變量(假設地址是A)加1,一般分為以下3個步驟:CPU 從主存中讀取地址A的數據到內部通用寄存器 x0(ARM64架構的通用寄存器之一)。通用寄存器 x0 加1。CPU 將通用寄存器 x0 的值寫入主存。
  • 3分鐘短文:太爽了,用Laravel寫API接口!
    本期為大家說一說用laravel寫restful風格的API,看看能有多簡單。以路由開端寫API接口,與傳統的渲染前端模板頁面有什麼區別?少了視圖,只需要準備好數據, 並按照規則格式化,返回就可以了。默認的驅動 token 定義在框架文件 laravel/framework/src/Illuminate/Auth/TokenGuard.php內。
  • 3分鐘短文|Laravel如何改造複雜的多表聯合查詢,這很高效!
    引言今天我們來說一下laravel框架裡最常用的資料庫模型操作,特別是功能複雜的應用程式, 往往會拆分出許多的業務表,關聯表,在時間和空間上進行權衡。那麼今天的問題是,如何關聯3張表進行操作?學習時間假設現在有3張表,分別是 articles 文章表,category 分類表,還要一個是 users 用戶表。 關聯度最深的還數 articles,因為它要存儲該文章的分類,還有發布者。
  • 面試官:說說你對keep-alive的理解是什麼?怎麼緩存當前的組件?緩存後怎麼更新?
    > beforeRouteLeave > deactivated二、使用場景使用原則:當我們在某些場景下不需要讓頁面重新加載時我們可以使用keepalive舉個慄子:當我們從首頁–>列表頁–>商詳頁–>
  • 妙到顛毫:你應該學會的 bigcache 優化技巧
    fast cache service with millions of entries in Go[3]做的一些調研和總結。遺憾的是,我們沒辦法要求用戶的緩存對象只能包含int、bool這樣的基本數據類型。解決辦法就是使用哈希值作為map[int]int的 key。把緩存對象序列化後放到一個預先分配的大的字節數組中,然後將它在數組中的 offset 作為map[int]int的 value。
  • 3分鐘短文|Laravel SQL篩選兩個日期之間的記錄,怎麼寫?
    引言今天說一個細分的需求,在模型中,或者使用laravel提供的 Eloquent ORM 功能,構造查詢語句時,返回位於兩個指定的日期之間的條目。應該怎麼寫?本文通過幾個例子,為大家梳理一下。如何實現在 from 和 to 之間的日期呢,類似下面這樣:SELECT * FROM table_name WHERE reservation_from BETWEEN '$from' AND '$to在laravel中你可以使用 whereBetween 這個查詢子句。
  • 3分鐘短文:Laravel模型一對一一對多關係真的亂嗎?
    引言laravel模型不但提供了可供資料庫操作的增刪改查,還附加了很多功能,最關鍵的要數模型的關聯關係。 本文說一說簡單的一對一,和一對多關係。用代碼說話,讓大家更直觀地理解。使用的時候,先獲取Contact條目,然後使用關聯方法獲取PhoneNumber對象, 代碼是這樣的:$contact= Contact::first();$contactPhone=$contact->phoneNumber;變量 $contactPhone 就是一個模型對象
  • 3分鐘短文:Laravel路由註冊,你必須掌握的「動詞」!
    本期為大家說一說用laravel註冊路由的那些必知必會的方法。這4條路由都是GET方式,如果使用其他HTTP標準的請求方式,可以如下註冊: 除了使用閉包返回數據,路由註冊也可以指向控制器方法,比如這樣: 動態路由需要用戶提供更多個輸入參數,所以在規劃路由上,可以使用佔位符接收路由地址的數據,比如這樣寫: 位置參數 id 在正確傳入數值之後,就會傳遞到指定的方法內
  • 吊打面試官系列:說說Integer緩存範圍
    * JLS協議要求緩存在-128到127之間(包含邊界值)     *     * The cache is initialized on first usage.  j = low;            // 緩存通過for循環來實現,創建範圍內的整數對象並存儲到cache數組中            // 程序第一次使用Integer的時候需要一定的額外時間來初始化該緩存            for(int k = 0; k < cache.length; k++){                cache[k] =
  • PHP(Laravel)用戶註冊、登錄和退出
    那麼這些功能,在 laravel 中實現,需要多久呢?是一星期、一天、還是一小時呢?正確的答案是1秒鐘。打開命令行,輸入php artisan make:auth出現有一個提示,說我們布局模板已經有了,是否還要重新創建一個?
  • ...半導體架構重新定義異構多核高速緩存一致性(Cache Coherence)
    比起目前系統級晶片(SoC)中常用的固定式和集中式高速緩存一致互連,它的可配置性更強。此外,Arteris的這項技術也能夠提高非高速緩存一致性(Non cache coherent)埠(Agent)的效能。