effiana/doctrine-cache-bundle
Installation (if still needed for legacy projects):
composer require effiana/doctrine-cache-bundle
Note: For Symfony 5+, skip this and configure Doctrine Cache manually via doctrine/cache package.
Enable the Bundle (Symfony <5 only):
Add to config/bundles.php:
return [
// ...
Effiana\DoctrineCacheBundle\EffianaDoctrineCacheBundle::class => ['all' => true],
];
First Use Case:
Configure a Doctrine cache driver (e.g., APCu) in config/packages/doctrine_cache.yaml:
doctrine_cache:
providers:
my_provider:
type: apcu
namespace: my_app_
Then use it in a repository:
use Doctrine\ORM\EntityRepository;
class MyEntityRepository extends EntityRepository
{
public function findCached($id)
{
$cache = $this->getEntityManager()->getCache();
$cacheKey = 'my_entity_' . $id;
if (!$cache->contains($cacheKey)) {
$entity = $this->find($id);
$cache->save($cacheKey, $entity);
} else {
$entity = $cache->fetch($cacheKey);
}
return $entity;
}
}
Query Result Caching: Cache entire query results (e.g., lists) to avoid repeated DB hits:
$cacheKey = 'all_users_' . $roleId;
if (!$cache->contains($cacheKey)) {
$users = $this->createQueryBuilder('u')
->where('u.role = :role')
->setParameter('role', $roleId)
->getQuery()
->getResult();
$cache->save($cacheKey, $users, 3600); // Cache for 1 hour
} else {
$users = $cache->fetch($cacheKey);
}
Entity Metadata Caching:
Leverage Doctrine’s built-in cache for metadata (e.g., metadata_cache provider):
doctrine_cache:
providers:
metadata_cache:
type: file
namespace: doctrine_metadata_
file: "%kernel.cache_dir%/doctrine/metadata"
Integration with Symfony Cache:
Bridge Doctrine Cache with Symfony’s CacheInterface (for Symfony 5+):
use Doctrine\Common\Cache\CacheProvider;
use Symfony\Component\Cache\Adapter\AdapterInterface;
$doctrineCache = new CacheProvider();
$symfonyCache = new AdapterInterface($doctrineCache);
app_) to avoid key collisions.postPersist, postRemove):
$this->getEntityManager()->getCache()->delete('my_entity_' . $id);
Deprecation Warning:
symfony/cache.# config/packages/doctrine.yaml
doctrine:
orm:
metadata_cache_driver: apcu
query_cache_driver: apcu
result_cache_driver: apcu
Cache Provider Quirks:
php-apcu extension. Fails silently if disabled.doctrine/cache + predis/php-memcached extensions.Key Collisions:
doctrine_) may clash with other bundles. Always specify a custom namespace.Serialization Issues:
__serialize()/__unserialize() or avoid caching them.var_dump($cache->getStats()); // For APCu/File
doctrine_cache:
providers:
my_provider:
type: apcu
namespace: my_app_
logging: true # Logs cache hits/misses
$cache->deleteAll(); // Clears all keys in namespace
Custom Cache Providers:
Extend Doctrine\Common\Cache\CacheProvider for bespoke storage (e.g., database):
class DbCacheProvider extends CacheProvider {
public function fetch($id) { /* Query DB */ }
public function save($id, $data, $lifeTime = 0) { /* Save to DB */ }
}
Register in services.yaml:
services:
App\Cache\DbCacheProvider:
tags: ['doctrine.cache_provider']
Event Listeners: Invalidate cache on entity changes:
use Doctrine\ORM\Event\LifecycleEventArgs;
class CacheInvalidator {
public function postRemove(LifecycleEventArgs $args) {
$entity = $args->getEntity();
$cache = $args->getEntityManager()->getCache();
$cache->delete('entity_' . spl_object_hash($entity));
}
}
Register as a service with tags: ['doctrine.event_listener'].
Symfony Cache Adapter:
For Symfony 5+, wrap Doctrine Cache in a Symfony CacheInterface:
use Symfony\Component\Cache\Adapter\DoctrineProviderAdapter;
$doctrineCache = new \Doctrine\Common\Cache\ApcuCache();
$symfonyCache = new DoctrineProviderAdapter($doctrineCache);
How can I help you explore Laravel packages today?