cache/doctrine-adapter
PSR-6 cache pool adapter backed by Doctrine Cache. Wraps Doctrine cache drivers (e.g., MemcachedCache) in a standards-compliant PSR-6 CacheItemPool for easy integration with php-cache features like tagging and hierarchy support.
Install the Package:
composer require cache/doctrine-adapter doctrine/cache
doctrine/cache is installed (required dependency).Configure Laravel Cache Driver:
Add the Doctrine adapter to config/cache.php:
'doctrine_memcached' => [
'driver' => 'doctrine',
'key' => env('CACHE_DOCTRINE_KEY', 'default'),
'store' => \Cache\Adapter\Doctrine\DoctrineCachePool::class,
'options' => [
'doctrine_cache' => new \Doctrine\Common\Cache\MemcachedCache(
new \Memcached(),
// Optional: Configure Memcached connection
['host' => 'localhost', 'port' => 11211]
),
],
],
First Use Case: Use the cache in a Laravel controller or service:
use Illuminate\Support\Facades\Cache;
// Store with tags
Cache::tags(['users', 'profiles'])->put('user:1', $userData, now()->addHours(1));
// Retrieve
$userData = Cache::tags(['users'])->get('user:1');
// Invalidate by tag
Cache::forgetTags(['users']);
Verify Integration:
Cache::forgetTags().{}()/@:` characters are used).// Store
Cache::put('key', $value, $ttl);
// Retrieve
$value = Cache::get('key');
// Delete
Cache::forget('key');
// Store with tags
Cache::tags(['products', 'electronics'])->put('product:101', $product, now()->addMinutes(30));
// Bulk invalidation
Cache::forgetTags(['products']); // Clears all tagged items
If using Doctrine’s hierarchical cache providers (e.g., ApcuCache + RedisCache), configure the adapter to leverage multiple layers:
$hierarchicalCache = new \Doctrine\Common\Cache\HierarchicalCache(
new \Doctrine\Common\Cache\ApcuCache(),
new \Doctrine\Common\Cache\RedisCache()
);
$pool = new DoctrineCachePool($hierarchicalCache);
Use the cache in queued jobs or commands:
Cache::put('job:result:123', $result, now()->addMinutes(5));
Leverage Laravel’s CacheResponseMiddleware for HTTP caching:
Route::middleware(['throttle:60', 'cache.headers'])->group(function () {
// Routes cached with headers
});
User).$user->save(); // Triggers observers/events
Cache::forgetTags(['users']); // Invalidate all user-related caches
Cache::remember() to repopulate caches on next request.{}()/@:`):
$sanitizedKey = Str::of($key)->replaceMatched('/[{}()\/\\@:]/', '');
Cache::put($sanitizedKey, $value);
app:) to avoid collisions:
Cache::tags(['app:users'])->put('app:user:1', $data);
$item = Cache::store('doctrine_memcached')->getItem('key');
logger()->debug('Cache hit', ['key' => $key, 'hit' => $item->isHit()]);
$doctrineCache = Cache::store('doctrine_memcached')->getStore();
if ($doctrineCache instanceof DoctrineCachePool) {
$stats = $doctrineCache->getDoctrineCache()->getStats();
logger()->debug('Doctrine Cache Stats', $stats);
}
Register the cache driver in a service provider:
use Cache\Adapter\Doctrine\DoctrineCachePool;
use Doctrine\Common\Cache\MemcachedCache;
public function register()
{
$memcached = new \Memcached();
$memcached->addServer('localhost', 11211);
$this->app->bind('doctrine.cache', function () {
return new DoctrineCachePool(new MemcachedCache($memcached));
});
}
Load cache configuration from environment variables:
'doctrine_redis' => [
'driver' => 'doctrine',
'key' => env('CACHE_DOCTRINE_KEY'),
'store' => DoctrineCachePool::class,
'options' => [
'doctrine_cache' => new \Doctrine\Common\Cache\RedisCache(
new \Redis(),
['prefix' => env('CACHE_REDIS_PREFIX', 'doctrine_')]
),
],
],
Implement a fallback to the file driver if the Doctrine cache fails:
try {
return Cache::store('doctrine_memcached')->get($key);
} catch (\Exception $e) {
return Cache::store('file')->get($key);
}
Use Laravel’s Cache facade in tests with a mock Doctrine cache:
use Doctrine\Common\Cache\ArrayCache;
$mockCache = new DoctrineCachePool(new ArrayCache());
Cache::shouldReceive('store')->andReturn(new CacheManager([
'doctrine' => $mockCache,
]));
{}()/@:`. Laravel’s Eloquent or custom key generation might include these.$key = Str::of($originalKey)->replaceMatched('/[{}()\/\\@:]/', '_');
Cache::put($key, $value);
app:) to avoid collisions and simplify sanitization.Cache::tags() behavior (e.g., wildcard support).Cache::tags(['users', 'admins'])->put('user:1', $data);
Cache::forgetTags(['users']); // Should clear 'user:1' but not 'admin:1'
memcached vs. doctrine_memcached):
php artisan cache:clear
# Run load tests and compare response times
Cache::remember() to minimize redundant operations.composer.json:
"cache/doctrine-adapter": "1.2.0",
"doctrine/cache": "1.11.0"
doctrine/dbal, doctrine/orm).composer why-not to resolve version conflicts:
composer why-not doctrine/cache
doctrine/cache to avoid version skew.Configure
How can I help you explore Laravel packages today?