Skip to content

Cache

簡介

friendsofhyperf/cache 使用 Laravel 風格的倉庫 API 封裝 hyperf/cache 提供的驅動。它支援 PSR-16 操作、命名儲存、門面訪問、快取事件、宏以及 stale-while-revalidate 快取。

安裝

shell
composer require friendsofhyperf/cache

該元件要求 Hyperf 3.2。其 ConfigProvider 會在容器中註冊 FriendsOfHyperf\Cache\Contract\FactoryFriendsOfHyperf\Cache\Contract\Repository

配置

該元件不會發布獨立的配置檔案。請透過 hyperf/cache 配置驅動和命名儲存; CacheManager::store($name) 會將名稱傳給 Hyperf 的快取管理器。預設倉庫解析 default 儲存。

獲取倉庫

依賴注入

注入 Contract\Repository 以使用預設儲存:

php
namespace App\Controller;

use FriendsOfHyperf\Cache\Contract\Repository;

class IndexController
{
    public function __construct(private Repository $cache)
    {
    }

    public function index(): mixed
    {
        return $this->cache->remember('users', 60, function () {
            return [];
        });
    }
}

需要命名儲存時注入 Contract\Factory

php
use FriendsOfHyperf\Cache\Contract\Factory;

$cache = $factory->store('redis');

門面

php
use FriendsOfHyperf\Cache\Facade\Cache;

$users = Cache::remember('users', 60, function () {
    return [];
});

$users = Cache::store('redis')->get('users');

Cache::driver($name)Cache::store($name) 的別名。 Cache::resolve($name) 會建立新倉庫,而不是返回管理器中快取的倉庫例項。

核心操作

倉庫實現了 Psr\SimpleCache\CacheInterface,因此可使用 get()set()delete()clear()getMultiple()setMultiple()deleteMultiple()has()。此外還提供以下擴充套件:

方法行為
get($key, $default = null)獲取單個專案;未命中時會執行可呼叫的預設值。傳入陣列會轉交給 many()
put($key, $value, $ttl = null)儲存單個專案;null 表示永久儲存,非正數 TTL 會刪除該鍵。傳入關聯陣列會轉交給 putMany(),並將第二個引數用作其 TTL。
putMany($values, $ttl = null)儲存多個專案;非正數 TTL 會刪除對應鍵。
forever($key, $value)不設定 TTL 地儲存單個專案。
add($key, $value, $ttl = null)僅當 get($key) 返回 null 時儲存專案。
many($keys)獲取多個鍵;關聯陣列輸入可為每個鍵提供預設值。
pull($key, $default = null)獲取專案後將其刪除。
remember($key, $ttl, Closure $callback)返回快取值,或按 TTL 儲存回撥結果。
rememberForever($key, Closure $callback) / sear(...)返回快取值,或永久儲存回撥結果。
increment($key, $value = 1) / decrement(...)讀取、調整並以無 TTL 方式儲存整數值。
flush()clear() 的別名。
missing($key)has($key) 的反向判斷。
getDriver() / getStore()返回底層 Hyperf DriverInterface

擴充套件倉庫方法接受的 TTL 可以是秒數、DateIntervalDateTimeInterface

行為邊界

倉庫會將已快取的 null 視為未命中。add()pull() 和遞增/遞減方法由分離的 操作實現,因此不是原子操作。雖然 pull() 接受 $default 引數,但當前實現不會 將它傳給 get(),鍵不存在時返回 null

Stale-While-Revalidate

flexible() 接受包含兩個 TTL 的陣列:第一個值是新鮮期,第二個值是快取值及其 內部建立時間戳使用的儲存 TTL。

php
use FriendsOfHyperf\Cache\Facade\Cache;

$users = Cache::flexible('users', [30, 300], function () {
    return [];
}, [
    'seconds' => 10,
    'owner' => 'users-refresh',
]);

快取未命中時,回撥立即執行。在新鮮期內直接返回快取值;新鮮期結束後返回舊值, 並透過延遲迴調嘗試在鎖內重新整理快取。如果其他程序已更新建立時間戳,則跳過重新整理。

使用 flexible() 前需要安裝兩個可選依賴:

shell
composer require friendsofhyperf/lock hyperf/coroutine

可選的鎖陣列接受 secondsowner,預設值分別為 0null

事件

當容器提供 Psr\EventDispatcher\EventDispatcherInterface 時,倉庫會為讀取、 寫入、刪除和清空操作分發事件:

  • CacheHitCacheMissedRetrievingKeyRetrievingManyKeys
  • WritingKeyWritingManyKeysKeyWrittenKeyWriteFailed
  • ForgettingKeyKeyForgottenKeyForgetFailed
  • CacheFlushingCacheFlushed

每個事件都包含儲存名稱。單鍵事件還包含鍵;適用時,寫入事件會公開值和 TTL, 批次事件會公開鍵,WritingManyKeys 還會公開值。批次讀取還會為每個返回的鍵分發 CacheHitCacheMissed

參考

該 API 的設計受 Laravel Cache 啟發,但具體行為應以本元件的契約和實現為準。