phpfluent/cache
phpfluent/cache brings a fluent, expressive API to caching in Laravel. Store, retrieve, remember, and forget values through chainable calls with TTL and tag support, keeping cache logic readable and out of your controllers.
composer show phpfluent/cache -a and check that the dist/source URLs are reachable. If Composer cannot fetch it, the package is archival — vendor a copy or stop here.composer.json (PHP constraint — a January 2018 release almost certainly targets PHP 7.x), the fluent entry class in src/, and any driver/adapter directory. The README is likely the only API documentation; copy it into your project before it disappears.remember behaves on a cache hit.A minimal bootstrap will look roughly like this — confirm the real entry class and chain order against the README, since fluent APIs are order-sensitive and there is no standard here:
$cache = new \PhpFluent\Cache\Cache(/* driver name or config array */);
$report = $cache->driver('file')
->ttl(300)
->remember('report:42', fn () => buildReport(42));
Cache-aside via remember. This is the package's core value proposition and how you will use it 80% of the time. Keep the closure pure and side-effect-free — anything that writes other cache keys or mutates state will produce confusing behavior on the hit path.
A single key factory. Because this is a fluent string-key cache, key collisions are the primary operational hazard. Route every key through one helper:
function cacheKey(string $entity, $id, int $version = 1): string
{
return sprintf('%s:%s:%s:v%d', getenv('APP_ENV'), $entity, $id, $version);
}
Prefixing with environment lets multiple apps share one Redis instance safely.
Driver swap per environment. Array or null driver in tests, file driver locally, Redis/Memcached in production. Bind the cache as a singleton in your container (or the framework's service container) and inject it — do not instantiate it at call sites, or you lose the ability to swap drivers in tests.
Wrap it behind PSR-16. Unless the package already implements Psr\SimpleCache\CacheInterface (verify with instanceof), write a thin adapter that does. This costs an hour and gives you a migration path off an unmaintained 2018 dependency without touching call sites.
Versioned keys instead of pattern deletes. Most backends do not support delete('prefix:*'). When data changes shape or a deploy invalidates a cache, bump the version segment in the key factory. It is atomic and driver-agnostic.
Test with the array driver and frozen time. Use the in-memory driver, clear it in setUp, and assert explicitly that your origin callable fired exactly once across two reads. For TTL, either inject a clock or keep TTLs short enough to actually expire within the test.
Explicit invalidation on write. After mutating an entity, call forget with the same key factory output. Do not rely on TTL expiry for correctness-sensitive reads.
composer.json, and commit a vendored copy or a fork so a Packagist disappearance cannot break your build.each(), curly-brace string offsets, implicitly nullable parameters, or dynamic properties. Run php -d error_reporting=E_ALL and a static analyzer (PHPStan/Psalm) over vendor/phpfluent/cache before trusting it in production.Psr\SimpleCache\CacheInterface / Psr\Cache\CacheItemPoolInterface explicitly; if absent, wrap rather than patch the vendor.0, null, -1, and omitted TTLs mean different things across file/Redis/Memcached backends. Test expiry behavior per driver, not just on the one you develop against. Watch for seconds-vs-minutes mismatches.serialize(); Redis may store raw strings. Objects containing closures, resources, or PDO handles will fail — cache scalars and plain arrays only.remember will not lock; under load a cold popular key can hammer your origin. Add a lock (Redis SET NX) around the expensive closure for hot keys.composer.lock — a 2018 release may pin old predis/memcached versions that conflict with your stack.How can I help you explore Laravel packages today?