openclassrooms/cache-bundle
OpenClassrooms CacheBundle is a Symfony bundle that adds configurable caching services, with cache adapters and pools to store frequently used data, reduce repeated work, and improve application response times.
This is a legacy Symfony 2 bundle, so the first thing to check is that your project is actually on Symfony 2.x (composer.json requiring symfony/symfony: ~2.x). On Symfony 3+ or 4+ you will fight the bundle registration and service wiring before you write a single line of caching logic — budget for that.
Minimal setup:
composer require openclassrooms/cache-bundle (add dev-master if no tagged release suits you).app/AppKernel.php:
new OpenClassrooms\Bundle\CacheBundle\OpenClassroomsCacheBundle(),
app/config/config.yml — typically a provider/backend choice (array, memcache, redis, etc.) plus optional TTL defaults.app/console cache:clear and confirm the service is registered with app/console container:debug | grep -i cache.Where to look first: read the bundle's DependencyInjection/Configuration.php and the service definition XML/YAML in Resources/config/. Those two files tell you the exact option names and the service ID you should inject — the README is usually thinner than the DI config.
First use case: cache one expensive thing — a Doctrine query result, a third-party API response, or a rendered controller fragment. Start with a single cache key, observe it in your backend (Redis MONITOR, or the array provider in dev), then expand. Do not retrofit caching across the app before you have one working call path.
In config_dev.yml, prefer the in-memory/array provider so cache misses and hits are visible and you aren't debugging stale Redis entries while developing.
Annotation-based controller caching. If the bundle exposes a @Cache-style annotation (common in this generation of bundles), the pattern is to annotate the action and let the listener short-circuit on a hit:
/**
* @Cache(ttl=300, key="product_show_{id}")
*/
public function showAction($id) { ... }
Keep the key deterministic and derived only from route/request parameters — not from time(), session, or user ID unless you explicitly want per-user partitioning.
Injecting a cache service for arbitrary data. For non-HTTP caching, inject the bundle's cache manager/service into your own service and wrap the expensive call:
$key = 'product_'.$id;
if (null === $data = $this->cache->get($key)) {
$data = $this->repository->findExpensive($id);
$this->cache->set($key, $data, 3600);
}
return $data;
Prefer this over Doctrine's result cache when you need to cache non-query work (API calls, rendering, aggregations).
HTTP cache + fragment caching. Combine the bundle with Symfony's HttpCache / ESI so full pages are served from the reverse proxy while only the expensive fragment hits this bundle. This is where the bundle earns its keep on a content-heavy site.
Cache warming as a deploy step. Add a console command or a post-deploy script that pre-populates keys that are predictable (homepage listings, sitemaps, category pages). Otherwise the first user after every deploy eats the latency — and on high-traffic pages that means a thundering-herd spike.
Key namespacing. Prefix keys with the app name and a version so you can invalidate everything on a schema change by bumping the version, instead of flushing the whole Redis instance:
$key = sprintf('app_v%d:product:%d', self::CACHE_VERSION, $id);
cache.app (PSR-6 / Symfony Contracts) later without touching call sites.null (or false, depending on version) on a miss, and the exact sentinel differs between adapters. Always compare against the documented miss value, not empty() — a cached 0 or [] is a legitimate hit.Response objects generally won't round-trip cleanly. Cache DTOs, arrays, or scalar values, and rebuild the Response in the controller.0 vs null. In several cache backends 0 means "never expire" while null means "use the default." Check the Configuration file — getting this backwards silently creates immortal cache entries that survive deploys.dev doesn't share state across requests the way Redis does, so hit rates look different and bugs like "second request returns stale data" only appear in prod. Run at least one smoke test with the production provider locally.FLUSHALL in production (don't).services.yml and override the alias. This survives composer updates and makes migration off the bundle trivial.intl-collated route parameters).How can I help you explore Laravel packages today?