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

Laravel Configurable Cache Laravel Package

salehhashemi/laravel-configurable-cache

A Laravel package for configurable caching that lets you define cache settings like TTL, keys, and stores per model or query instead of hardcoding them, keeping cache logic centralized and easy to adjust across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and let Laravel's package discovery register the service provider:

composer require salehhashemi/laravel-configurable-cache
php artisan vendor:publish --tag=configurable-cache-config

Open config/configurable-cache.php first — this is the contract the whole package is built around. Expect to see something like named cache "profiles" or per-context blocks, each defining a store, ttl, and prefix. Read the README alongside the config file; with a 21-star package the config file is the most reliable documentation of the actual API surface.

Your first use case should be replacing a hand-rolled Cache::remember(...) call in one hot path. Pick an expensive query or a third-party API response, define a named profile for it (e.g. dashboard_stats with a 5-minute TTL on the redis store), and resolve the manager via the facade or constructor injection:

use SalehHashemi\ConfigurableCache\Facades\ConfigurableCache;

$stats = ConfigurableCache::profile('dashboard_stats')
    ->remember(fn () => $this->calculateStats());

Before writing more code, run php artisan config:show configurable-cache and confirm the resolved values, then verify the manager resolves the expected store with Cache::store(...)->getStore()->getName(). Once that single path works end to end, expand method by method — the package's value is consistency across many cache call sites, not one-off features.

Implementation Patterns

Named profiles as the unit of configuration. The idiomatic workflow is to define one profile per logical cache domain (per feature, per model aggregate, per external API) and reference it by name everywhere. This centralises TTL and store decisions so a single config edit re-tunes the whole app. Treat profile names as part of your public interface and keep them in a constants class or enum so typos fail fast at boot rather than silently falling into a different cache key.

Dependency injection over the facade. For services and jobs, inject the manager contract rather than using the facade. This makes your code testable with a fake and mirrors how Laravel's own Repository contract is used. Reserve the facade for views, Blade, and quick console snippets.

Wrap the remember call, not the query. The most reliable integration point is around the expensive boundary — an Eloquent query builder chain, an HTTP client call, a report generator. Keep the closure pure and serialisable: never capture $this, request objects, or Auth::user() inside the closure unless you include the user ID in the cache key material. A common pattern is a small CachesQueries trait on your repositories that takes a profile name and a key suffix.

Key composition. Build keys from a stable, deterministic tuple — model class, ID, and a hash of the parameter array — and let the profile prefix handle namespace isolation. Avoid time() or random values in keys. If the package exposes a key-builder helper, use it; otherwise centralise key building in one class so you can change the scheme (e.g. adding a version segment) in one place later.

Invalidation as a workflow. Caching is only half the job. Standardise on forget() calls inside model observers (saved, deleted) and job finally blocks, and prefer "write-through" — recompute and re-store after a mutation — over blind invalidation when the recompute is cheap. If the package supports tag-like grouping, group related keys under the profile name so a single flush can clear a feature's entire cache surface.

Testing. Bind the manager to Laravel's array store in your test suite via phpunit.xml env or a TestCase setup override. Because profiles are config-driven, you can also override a single profile's TTL to 0 in a test to force a miss and assert recomputation. Add one integration test per profile that exercises remember twice and asserts the closure ran once — this catches configuration drift cheaply.

Environment-tiered config. Because everything flows from config, use config/configurable-cache.php to encode environment differences: short TTLs locally, longer in production, array in tests. Wrap values in env() calls only in the base config file, then never call env() elsewhere.

Gotchas and Tips

  • Early-stage package risk. With ~21 stars, zero dependents, and a NOASSERTION license, treat this as pre-1.0 software. Pin the version in composer.json, read the changelog on every bump, and keep an abstraction boundary (one small wrapper class) so you can swap it out in an afternoon.
  • config:cache traps. Any dynamic profile registration at runtime — inside a service provider that reads a database or a tenant ID — will break under config:cache in production. Keep profiles purely declarative in the config file, or register them during boot only.
  • TTL semantics. Verify explicitly whether null, 0, and a missing ttl key mean "forever", "no cache", or "fall back to the store default". These three outcomes differ across drivers and across cache packages, and a silent 0 → permanent cache is a classic production incident. Write a one-line test asserting each.
  • Prefix collisions. If profiles share a store and the package's prefix defaults are empty or derived from the profile name only, two features can hash to the same key. Set an explicit, unique prefix per profile and audit redis-cli --scan --pattern 'yourprefix:*' after a deploy.
  • Serialisation. Caching Eloquent models or DTOs with a redis or memcached store serialises them; stale models then hydrate with outdated attributes. Cache scalars/arrays or plain arrays produced by toArray() unless you deliberately want detached snapshots, and set a short TTL if you do.
  • Stale-cache debugging loop. When a value "won't update", check in this order: (1) is the app hitting the store you think — log the driver name; (2) is the config cached — run php artisan config:clear; (3) is the key what you expect — dump the computed key once; (4) is a worker or Octane process holding an in-memory copy on the array store.
  • Octane and long-running workers. Any in-process state in the manager (resolved profiles, memoised config) must be reset on each Octane request via a listener, or you'll serve a previous request's profile. Verify the package ships an Octane-compatible reset hook; if not, add one.
  • Extension points to inspect. If the manager is bound as a singleton in the container, you can extend it with $this->app->extend(...) to add methods or decorate the store without forking. Prefer that over editing vendor code, so upgrades stay clean.
  • Observability. Wrap the manager's resolve call in a small helper that logs profile name, key, hit/miss, and duration in non-production. Cache bugs are nearly always key or TTL bugs, and you cannot debug what you cannot see.
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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox