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

Doctrine Cache Extension Bundle Laravel Package

openclassrooms/doctrine-cache-extension-bundle

A Symfony bundle from OpenClassrooms that integrates Doctrine Cache extension capabilities, providing configuration and services to simplify caching for Doctrine-based applications. It helps wire cache providers and related services into Symfony projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. This is a Symfony2 bundle, not a Laravel package. It extends Doctrine's cache layer with additional cache providers and wires them into the Symfony DI container. There is no Illuminate\Support\ServiceProvider, no facade, no config/ file that Laravel's package discovery will pick up. Installing it in a Laravel app does nothing until you manually reach into it.

Step 1 — install and inspect.

composer require openclassrooms/doctrine-cache-extension-bundle

Then look at, in this order:

  1. vendor/openclassrooms/doctrine-cache-extension-bundle/*Bundle.php — confirm it extends Symfony\Component\HttpKernel\Bundle\Bundle. That tells you it will never self-register in Laravel.
  2. DependencyInjection/*Extension.php and Resources/config/services.* — this is where the actual cache provider services and the config tree (the bundle's config key) are defined. This is the only part that matters to a Laravel dev.
  3. The provider classes it exposes (subclasses of Doctrine\Common\Cache\CacheProvider) — these are plain PHP classes you can instantiate from Laravel.

Step 2 — decide your integration path. There are only two:

  • Porting a Symfony2 app: use the bundle as intended (register in AppKernel/bundles.php, configure under its config key, inject the cache services).
  • Laravel app: ignore the bundle entirely and use the underlying cache provider class directly, or just use Illuminate\Support\Facades\Cache. The bundle's value-add (service registration, config tree) is Symfony-only.

First use case — a cache-aside wrapper around a slow query or remote API call:

use Doctrine\Common\Cache\CacheProvider;

// A provider class shipped/aliased by the bundle's vendor dir
$cache = new \OpenClassrooms\DoctrineCacheExtension\Provider\SomeCacheProvider();
$cache->setNamespace('orders:v1');

$orders = $cache->fetch($key);
if ($orders === false) {
    $orders = Order::with('items')->where('status', 'paid')->get()->toArray();
    $cache->save($key, $orders, 300); // 5 min TTL
}

Bind it once in a service provider so you don't re-instantiate per call:

// app/Providers/AppServiceProvider.php
$this->app->singleton(CacheProvider::class, function () {
    $cache = new \OpenClassrooms\DoctrineCacheExtension\Provider\SomeCacheProvider();
    $cache->setNamespace(config('app.name') . ':cache');
    return $cache;
});

Implementation Patterns

Decorator around repositories/queries (the main pattern). Keep cache logic out of controllers and models. Wrap the data access:

final class CachedOrderRepository
{
    public function __construct(
        private OrderRepository $inner,
        private CacheProvider $cache,
    ) {}

    public function paid(): array
    {
        $key = 'paid:' . md5(json_encode([request()->query()]));
        if (($hit = $this->cache->fetch($key)) !== false) {
            return $hit;
        }
        $rows = $this->inner->paid()->toArray(); // cache arrays, not models
        $this->cache->save($key, $rows, 300);
        return $rows;
    }
}

Bind the decorator in a service provider and let the concrete repository stay cache-agnostic.

Provider selection from config. Mirror config/cache.php with a factory so you can swap providers per environment (Redis in prod, ArrayCache in tests):

$this->app->singleton(CacheProvider::class, function ($app) {
    $cache = $app->make(config('cache.doctrine.provider')); // class-string
    $cache->setNamespace(config('cache.prefix'));
    return $cache;
});

Tags / namespaces for invalidation. Doctrine providers support setNamespace() and deleteAll()/flushAll() (provider-dependent). Namespace per aggregate (orders:v2) and bump the version suffix on schema changes rather than trying to surgically invalidate.

Cache-aside in HTTP clients. The same decorator shape works around a Guzzle client for third-party payloads — this is often where a Doctrine provider is genuinely nicer than Laravel's facade because you get fetch()'s false miss semantics and provider-level stats.

Testing. Swap the bound provider to Doctrine\Common\Cache\ArrayCache in the test container so each test starts cold and assertions don't hit Redis.

When to not use it. If you're not porting Symfony2 code, Cache::remember() already does cache-aside with tags, locking, and multiple stores. The only reason to reach for this package is a specific provider behavior the bundle exposes that Laravel's stores don't.

Gotchas and Tips

  • It will not auto-register. Laravel's package discovery only looks at extra.laravel.providers. A Symfony Bundle subclass is invisible to it; no error, it just silently does nothing.
  • Doctrine Cache 1.x vs 2.x is the big trap. Doctrine\Common\Cache\CacheProvider and the fetch/save/contains/delete API are removed in doctrine/cache 2.0; the modern replacement is PSR-6/PSR-16 via symfony/cache. Check composer.lock — this bundle's constraint likely pins doctrine/cache ^1.x, which conflicts with anything pulling 2.x. Expect composer why-not fights.
  • Symfony2-era maintenance. Zero stars, zero dependents, Symfony2 (circa PHP 5.5–7.0). Expect PHP 8 constraint clashes, deprecated mcrypt/Memcache drivers, and no security fixes. Audit before adding to a production Laravel app — a composer audit and a php -l pass over the provider classes costs five minutes.
  • Serialization footguns. Storing Eloquent models in a Doctrine cache round-trips them through serialize(); connections, dates, and closures in attributes will break on read. Cache arrays/DTOs only, or explicitly implement __serialize/__sleep.
  • Miss semantics. fetch() returns false on miss — a legitimately cached false or 0 is indistinguishable. Wrap values (['v' => $value]) or use contains() before fetch().
  • Key collisions. Without setNamespace() you will collide in shared Redis/Memcached instances across apps and environments. Always prefix with app name + environment, and version it.
  • save() returns a bool; check it. Silent write failures (full Memcached, oversized value >1MB, Redis maxmemory) are the most common "cache doesn't work" bug. For debugging, getStats() on providers that support it, and log save() failures.
  • No cache:clear console command in Laravel. The bundle's console integration is Symfony-only; you'll write your own artisan command calling deleteAll() or flushAll().
  • Extension point that actually matters: rather than subclassing the bundle's providers, write an adapter implementing Illuminate\Contracts\Cache\Repository and register it via Cache::extend(). Then the rest of your Laravel code uses the normal Cache facade while you get the Doctrine provider underneath.
  • Verdict for a Laravel team: treat this as a reading reference, not a dependency. Skim the DI extension to see how they configured providers, then either use doctrine/cache 1.x providers standalone or (preferably) migrate to symfony/cache PSR-6 adapters, which are maintained and framework-agnostic.
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