Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cache Laravel Package

webman/cache

Cache component for the Webman framework, providing a PSR-16 simple cache API with multiple drivers including file, Redis, APCu, and in-memory array storage. Works with Workerman's event loop for fast, reliable caching in high-performance PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat it as first-party, not as a 3‑star package. webman/cache is the official cache component for the webman framework and provides the support\Cache facade the docs use everywhere. The GitHub star count and "0 dependents" reflect how PHP packages are consumed (via Packagist inside webman skeletons), not the actual footprint.

Minimal setup:

composer require webman/cache
  1. Look here first: config/cache.php. It defines default plus a stores map (typically file, redis, array). If your skeleton doesn't ship it, copy the sample from the repo README — every behaviour you care about is decided in this file.
  2. Second stop: vendor/webman/cache/src — the manager that maps driver strings to Symfony cache adapters. That file is the source of truth for which options each driver accepts (path, connection, prefix/namespace, lifetime).
  3. Then the API: support\Cache is a thin static wrapper over a PSR‑16 (Psr\SimpleCache\CacheInterface) store. If you know PSR‑16, you already know 90% of it.

First use case — protect an expensive call:

use support\Cache;

$stats = Cache::get('dashboard:stats');
if ($stats === null) {
    $stats = $repo->expensiveAggregate();   // 800ms query
    Cache::set('dashboard:stats', $stats, 60); // 60s TTL
}
return json_encode($stats);

Sanity check after wiring it up: hit the route once and confirm the artefact appears (runtime/cache/ for the file driver, or scan keys in Redis for the redis driver). That one check catches 80% of misconfiguration.

Implementation Patterns

Static facade for the common case, named stores for the exceptions. Use Cache::* for the default store and Cache::store('redis') when a code path needs a different lifetime or backend (e.g. array in tests, redis for anything shared across workers).

Cache::store('redis')->set('lock:report', 1, 30);
Cache::store('array')->set('k', 'v');        // per-process, ideal for tests

Cache-aside with a remember helper. PSR‑16 has no remember, so own it in your app layer rather than scattering get/set pairs:

function remember(string $key, int $ttl, callable $cb, ?string $store = null)
{
    $cache = $store ? Cache::store($store) : Cache::store();
    $value = $cache->get($key, $sentinel = new stdClass());
    if ($value !== $sentinel) {
        return $value;
    }
    $value = $cb();
    $cache->set($key, $value, $ttl);
    return $value;
}

The sentinel matters — see the gotchas below on null values.

Key conventions before you write a single key. Pick a scheme on day one: {app}:{version}:{entity}:{id}:{variant}, e.g. shop:v2:product:814:detail. Version bumps (v2) let you invalidate an entire shape of cached payloads without clear(). Namespace per tenant if you're multi-tenant on a shared Redis DB.

Batch operations. Use getMultiple / setMultiple / deleteMultiple for warming lists (product grids, config maps) — one round trip instead of N on Redis.

$keys = array_map(fn($id) => "shop:v2:product:$id", $ids);
$missing = array_diff_key(array_flip($keys), Cache::getMultiple($keys));

Invalidation on write, TTL as backstop. Delete specific keys inside the write path (Cache::delete("shop:v2:product:$id")), and let TTL handle anything you forgot. Do not reach for clear() in production.

Driver by environment. file is fine for single-host dev and cheap read-mostly data; redis (via your existing config/redis.php connection name) is the correct production default under Workerman, because every worker process needs to see the same cache. array is for tests and request-scoped scratch data only.

Testability. Bind Psr\SimpleCache\CacheInterface in the container to Cache::store('array'), or swap in an in-memory fake. Code that type-hints the interface instead of calling support\Cache statically is trivially testable — worth the small extra indirection on services you actually unit test.

Warm-up strategy. If you warm caches in onWorkerStart, remember every worker runs it; either accept the duplicate work (it's usually cheap) or gate it to a single worker with a Redis SETNX so you don't stampede the DB on deploy.

Gotchas and Tips

  • Reserved characters in keys. PSR‑16 forbids { } ( ) / \ @ : in keys and throws InvalidArgumentException. Raw URLs and emails will blow up. Hash or sanitise: 'url:' . md5($url).
  • null vs "not found". Cache::get($k, $default) returns $default both when the key is missing and when the stored value is null. If you cache nulls or falsy payloads, use Cache::has($k) to disambiguate, or the sentinel-object pattern above.
  • clear() is a blunt instrument. Depending on the adapter it wipes the whole store/namespace — on Redis that can mean dropping keys belonging to other apps sharing the DB. Prefer explicit deletes; if you must bulk-invalidate, use a versioned key prefix you can abandon.
  • TTL zero and negatives. Symfony adapters treat 0/negative TTLs as "expire immediately" or fall back to the adapter's default lifetime depending on version. Use a positive int for seconds and null for "adapter default"; don't rely on 0 meaning "forever".
  • The Redis store does not write plain keys. Symfony's RedisAdapter prefixes and marshals values, so redis-cli GET user:1 won't show what you expect. Debug with redis-cli --scan --pattern '*<yourprefix>*' and inspect through the cache API, not by hand.
  • File store and deploys. runtime_path()/cache needs to be writable by the worker user — a classic Docker/first-deploy failure. Conversely, a deploy that wipes runtime/ wipes your cache: usually desirable, and it hides the "cached object shape changed after release" class of bugs only if you store arrays rather than serialised objects.
  • Store scalars and arrays, not live objects. Objects serialise fine today and break silently when you change a class or switch drivers. Convert DTOs to arrays at the boundary.
  • array store is per-process. Under Workerman each worker has its own; it is not a cache in any meaningful production sense.
  • No built-in stampede protection. There's no lock or single-flight in PSR‑16. If a cold key can trigger a thundering herd, add a lock (webman/redis, symfony/lock) around the recompute.
  • Check the boolean. set() returns false on failure rather than throwing. Anywhere the cache is load-bearing (rate limits, idempotency keys), branch on the return value.
  • Symfony version coupling. The package rides on symfony/cache; adapter behaviour and constructor signatures shift across Symfony majors. Pin and upgrade deliberately, and re-read vendor/webman/cache/src when you do — it's ~200 lines and answers every "which option does this driver take?" question faster than the README.
  • Extension point. If you need a backend that isn't mapped, implement Psr\SimpleCache\CacheInterface and wrap your own client, then expose it through your app's service layer rather than patching the manager — that keeps the upgrade path clean.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource