goletter / hyperf-cache
Laravel-style cache repository for Hyperf.
Requires
- php: >=8.1
- hyperf/cache: ~3.1.0 || ~3.2.0
- hyperf/collection: ~3.1.0 || ~3.2.0
- hyperf/context: ~3.1.0 || ~3.2.0
- hyperf/macroable: ~3.1.0 || ~3.2.0
- hyperf/support: ~3.1.0 || ~3.2.0
- hyperf/tappable: ~3.1.0 || ~3.2.0
- nesbot/carbon: ^2.0 || ^3.0
Requires (Dev)
None
Suggests
- friendsofhyperf/lock: Required to lock stale-while-revalidate refresh (~3.1.0 || ~3.2.0).
- hyperf/coroutine: Required to defer stale-while-revalidate refresh (~3.1.0 || ~3.2.0).
Provides
None
Conflicts
None
Replaces
None
README
Introduction
goletter/hyperf-cache wraps the drivers provided by hyperf/cache with a
Laravel-style repository API. It supports PSR-16 operations, named stores,
facade access, a cache() helper, cache events, macros, and
stale-while-revalidate caching.
Namespace: Goletter\Cache.
Installation
composer require goletter/hyperf-cache
Requires Hyperf 3.1 or 3.2. ConfigProvider registers
Goletter\Cache\Contract\Factory and
Goletter\Cache\Contract\Repository in the container.
Configuration
This component does not publish a separate configuration file. Configure
drivers and named stores through hyperf/cache; CacheManager::store($name)
passes the name to Hyperf's cache manager. The default repository resolves the
default store.
Accessing a Repository
Dependency Injection
Inject Contract\Repository for the default store:
namespace App\Controller; use Goletter\Cache\Contract\Repository; class IndexController { public function __construct(private Repository $cache) { } public function index(): mixed { return $this->cache->remember('users', 60, function () { return []; }); } }
Inject Contract\Factory when a named store is required. Calls on the factory
are forwarded to the default store ($factory->remember(...)).
use Goletter\Cache\Contract\Factory; $cache = $factory->store('redis');
Helper
cache(); // default Repository cache('users'); // get cache(['users' => $users], 60); // putMany
Facade
use Goletter\Cache\Facade\Cache; $users = Cache::remember('users', 60, function () { return []; }); $users = Cache::store('redis')->get('users');
Cache::driver($name) is an alias of Cache::store($name).
Cache::resolve($name) creates a new repository instead of returning the
manager's cached repository instance.
Cache::purge($name) forgets a cached repository instance.
Core Operations
The repository implements Psr\SimpleCache\CacheInterface, so get(), set(),
delete(), clear(), getMultiple(), setMultiple(), deleteMultiple(),
and has() are available. It also provides these extensions:
| Method | Behavior |
|---|---|
get($key, $default = null) |
Retrieves one item; a callable default is evaluated on a miss. Passing an array delegates to many(). |
put($key, $value, $ttl = null) |
Stores one item; null means forever and a non-positive TTL deletes the key. Passing an associative array delegates to putMany(), with the second argument used as its TTL. |
putMany($values, $ttl = null) |
Stores multiple items; a non-positive TTL deletes their keys. |
forever($key, $value) |
Stores one item without a TTL. |
add($key, $value, $ttl = null) |
Stores the item only when get($key) returns null. |
many($keys) |
Retrieves multiple keys; associative input may provide per-key defaults. |
pull($key, $default = null) |
Retrieves (with default) and then deletes an item. |
remember($key, $ttl, Closure $callback) |
Returns the cached value or stores the callback result with a TTL. |
rememberForever($key, Closure $callback) / sear(...) |
Returns the cached value or stores the callback result forever. |
increment($key, $value = 1) / decrement(...) |
Prefer driver increment when available; otherwise read-modify-write without a TTL. |
flush() |
Alias of clear(). |
missing($key) |
Inverse of has($key). |
getDriver() / getStore() |
Returns the underlying Hyperf DriverInterface. |
TTL values accepted by the extended repository methods may be seconds,
DateInterval, or DateTimeInterface.
::: warning Behavioral boundaries
The repository treats a cached null as a miss. add() is get-then-put, so it
is not atomic. increment() / decrement() use the driver increment method
when present; otherwise they are read-then-write and not atomic.
:::
Stale-While-Revalidate
flexible() accepts a two-item TTL array: the first value is the fresh period
and the second is the storage TTL used for both the cached value and its
internal creation timestamp.
use Goletter\Cache\Facade\Cache; $users = Cache::flexible('users', [30, 300], function () { return []; }, [ 'seconds' => 10, 'owner' => 'users-refresh', ]);
On a miss, the callback runs immediately. During the fresh period, the cached value is returned. After the fresh period, the stale value is returned and a deferred callback attempts to refresh it under a lock. A refresh is skipped if another process has already updated the creation timestamp.
friendsofhyperf/lock and hyperf/coroutine are optional. Without lock, refresh
still runs (without mutual exclusion). Without defer, refresh runs inline.
composer require friendsofhyperf/lock hyperf/coroutine
The optional lock array accepts seconds and owner; they default to 0 and
null.
Events
When the container provides Psr\EventDispatcher\EventDispatcherInterface,
the repository dispatches events for reads, writes, deletes, and flushes:
CacheHit,CacheMissed,RetrievingKey,RetrievingManyKeysWritingKey,WritingManyKeys,KeyWritten,KeyWriteFailedForgettingKey,KeyForgotten,KeyForgetFailedCacheFlushing,CacheFlushed
RetrievingKey is dispatched before the underlying read.
Each event includes the store name. Single-key events also include the key,
write events expose the value and TTL where applicable, and bulk events expose
their keys; WritingManyKeys also exposes the values. Bulk reads additionally
dispatch CacheHit or CacheMissed for each returned key.
Migration from friendsofhyperf/cache
Replace imports:
- use FriendsOfHyperf\Cache\...; + use Goletter\Cache\...;
And require goletter/hyperf-cache instead of friendsofhyperf/cache.
Reference
The API is inspired by Laravel Cache, but behavior should be verified against this component's contracts and implementation.