marko/cache
A caching package for Marko/Laravel applications offering a simple, consistent API for storing and retrieving cached data across multiple drivers. Supports cache tags, TTLs, and flexible backends to speed up your PHP apps.
This package is a read-only split of the marko-php/marko monorepo; it ships the cache contracts and infrastructure, not a standalone application dependency. In practice you almost never composer require marko/cache directly — it arrives transitively when you install the framework or a component that needs caching. If you do need it in isolation (e.g., building a custom integration), add it and pull the implementation package your driver needs.
Where to look first, in order:
src/ — find the primary contract (typically CacheInterface) and the CacheManager/factory that resolves drivers. Read the interface signatures before anything else; they define the whole surface you'll code against.get/set/delete/remember semantics.First use case: wrap an expensive read (a DB aggregate, a third-party API call, a rendered fragment) so subsequent requests hit the cache. Something like resolving the cache from the container, checking for a key, and falling back to the source on a miss.
Cache-aside with remember. The dominant pattern. Prefer the remember($key, $ttl, $callback) style so the check-compute-store sequence lives in one place and the miss path is exercised the same way every time. Use rememberForever sparingly — prefer an explicit TTL even if it's long.
Inject the contract, not the manager. Type-hint CacheInterface in constructors and let the container wire the configured driver. Reserve the CacheManager for code that genuinely needs to select a driver at runtime (multi-store setups, admin tooling).
Namespacing keys deliberately. Build keys with a prefix per domain — user:{id}:profile, report:{hash}:v3. Version tokens in the key (the v3 above) are a cheap, driver-agnostic invalidation strategy and often preferable to tags when drivers differ across environments.
Tags for group invalidation. Where the driver supports tags, use them for "invalidate everything tied to this entity" flows (e.g., flush a customer's cached views on update). Isolate the calls behind a small repository/service wrapper so a tag-less driver doesn't leak into call sites.
Decorator pattern for repositories. Wrap a repository in a CachedUserRepository that delegates to the real one on miss. This keeps cache concerns out of the data layer and makes it easy to disable caching in tests by injecting a passthrough decorator.
Fragment caching in the view layer. For rendered partials, cache the rendered string keyed by the data that feeds it, not the whole page. This gives you granular invalidation and avoids blowing away an entire layout for a single stale component.
Testing switch. Bind the array driver in your test container so each test gets a clean, in-memory store. If your tests assert "no cache hit," make the array store explicit rather than relying on a null driver.
marko-php/marko monorepo. Don't open PRs here, and don't vendor-patch — you'll lose the change on the next split. If this package is a blocker, that's a strong reason to file upstream.DateInterval/DateTimeInterface. Mixing the two silently produces caches that never expire or expire immediately. Check the driver's test for the authoritative behavior.null/false results (recommendation: cache them with a short TTL to avoid penning repeated misses).increment/decrement, and TTL precision vary by driver. If you rely on any of these, write a smoke test and run it against every driver you deploy.CacheInterface is the sanctioned way to add a backend, and a decorated cache is the sanctioned way to add cross-cutting behavior (logging, metrics, key prefixing) without touching call sites.CacheInterface — it's a five-minute change and beats sprinkling var_dump in your services.How can I help you explore Laravel packages today?