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

openclassrooms/cache

openclassrooms/cache is a straightforward caching package for PHP applications. It lets you store and retrieve reusable data to avoid redundant work, improve response times, and simplify everyday caching needs. Lightweight and easy to integrate into OpenClassrooms-style projects.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install via Composer (check the repo's composer.json for the PHP version and the doctrine/cache constraint before you install — this package pins to the pre-PSR-6 Doctrine Cache line):

    composer require openclassrooms/cache
    
  2. Read src/ before the README. With a package this small and this lightly adopted, the source is the documentation. Look for:

    • the class extending Doctrine\Common\Cache\CacheProvider (or Cache);
    • any factory/provider classes (Redis, Memcached, Array, File, Chain);
    • the constructor signatures — this tells you exactly what the "extension" over stock Doctrine Cache is.
  3. Confirm the Doctrine Cache namespace in use. Older versions use Doctrine\Common\Cache\*; the newer split uses Doctrine\Cache\*. Match the import in src/ to avoid a fatal class-not-found at boot.

  4. Wire it into the Laravel container in a service provider so you never instantiate it inline:

    // app/Providers/AppServiceProvider.php
    $this->app->singleton(\OpenClassrooms\Cache\...::class, function ($app) {
        return new \OpenClassrooms\Cache\...(
            new \Doctrine\Common\Cache\RedisCache(/* ... */)
        );
    });
    
  5. First use case: cache an expensive read (a dashboard aggregate, a third-party API payload, a rendered fragment) behind a stable key, with an explicit TTL. Prove the read-through path works, then prove invalidation works. If invalidation doesn't behave as expected, stop and read Gotchas below before layering it into more code.

Implementation Patterns

Read-through with an explicit miss path. The Doctrine contract is fetch() returning false on a miss. Wrap it in a small helper so callers don't repeat the === false dance:

public function remember(string $key, int $ttl, callable $resolve)
{
    $value = $this->cache->fetch($key);

    if ($value === false) {
        $value = $resolve();
        $this->cache->save($key, $value, $ttl);
    }

    return $value;
}

Decorator around repositories, not inside models. Keep Eloquent models cache-agnostic. Put caching in a repository or query-object decorator so the domain layer stays testable and swapping the cache backend is a one-line binding change.

Chain cache for hot reads. Stock Doctrine ships ChainCache. If this package wraps it, use ArrayCache (request-scoped) in front of Redis so a single request that reads the same value ten times hits the network once. Bind the chain as the singleton and the individual providers as named bindings.

Namespace your keys aggressively. Every key should carry an app/domain prefix (oc:users:{id}:profile). This is the single cheapest protection against a shared Redis instance and against a second package writing to the same keyspace.

Invalidation via versioned keys, not delete. For collections (list of users, product catalogue), keep a version counter and embed it in the key. On write, bump the counter; the old keys age out by TTL. This avoids trying to deleteMultiple an unbounded key set.

Warmers as Artisan commands. Any "build the cache" logic belongs in a php artisan cache:warm command so deploys and cron can prime the cache instead of users eating the cold-start latency.

Test with the Array/Null provider. Bind ArrayCache (or NullCache) in the test environment so the suite never touches Redis and cache behaviour is deterministic per test. Add one integration test against the real backend.

Gotchas and Tips

  • Doctrine Cache is effectively legacy. It was superseded by PSR-6/PSR-16 and Symfony Cache. If this package is a thin wrapper, treat it as a stopgap and keep your own caching helper thin so migration to symfony/cache or Laravel's own Cache facade is a swap of one class. Don't let the package's types leak into domain signatures.
  • Miss semantics are false, not null. If you cache a legitimate false (a boolean flag, a "not found" marker), fetch() is indistinguishable from a miss. Wrap booleans in an array or use contains() alongside fetch().
  • TTL 0 means "forever" in Doctrine Cache. Passing 0 from a config default silently creates immortal keys. Always pass a positive int or explicitly document "no expiry".
  • No auto-discovery assumed. With zero dependents this package almost certainly ships no Laravel PackageManifest service provider. Register the binding yourself; don't expect php artisan vendor:publish to do anything.
  • Serialization. RedisCache/MemcachedCache serialize values. If you cache Eloquent models, you're serializing a lot more than you think (and rehydrating detached instances). Cache arrays/scalars or DTOs, never models.
  • Memcached's 250-byte key limit and 1 MB value limit bite silently. Hash long, descriptive keys — md5($key) loses debuggability, so prefer substr plus a short hash suffix and log the original key on write.
  • getStats() is your first debugging tool. If a key "isn't being set", check stats before blaming TTL: it tells you hit/miss counts and whether a write ever landed.
  • Namespace flushing vs deleteAll(). deleteAll() on a namespace can be O(n) or blocked on some backends (Redis scans). In production prefer the versioned-key pattern from above; reserve deleteAll() for dev and tests.
  • Cache stampede. With this stack you get no built-in locking, so N concurrent misses for the same key all hit the database. Add a short jitter to TTLs and a Redis SETNX lock around expensive resolvers.
  • Pin the version. No stars and no dependents means little forward-compatibility pressure on the maintainers. Pin an exact version in composer.json and read the diff before bumping.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource