cache/illuminate-adapter
PSR-6 cache pool adapter for Laravel Illuminate cache stores. Wrap any Illuminate\Cache\Store (e.g., ArrayStore) to use via standard PSR-6 CacheItemPoolInterface. Part of the PHP-Cache organization with shared docs on tags and hierarchy.
Installation:
composer require cache/illuminate-adapter
Basic Setup:
use Illuminate\Cache\FileStore;
use Cache\Adapter\Illuminate\IlluminateCachePool;
// Initialize Laravel's cache store (e.g., FileStore, RedisStore)
$store = new FileStore();
// Wrap it with the PSR-6 adapter
$cachePool = new IlluminateCachePool($store);
First Use Case:
// Store an item
$item = $cachePool->getItem('key');
$item->set('value');
$cachePool->save($item);
// Retrieve an item
$retrievedItem = $cachePool->getItem('key');
$value = $retrievedItem->value(); // 'value'
Leverage Laravel’s Configuration:
Use Laravel’s existing cache configuration (e.g., config/cache.php) to initialize the store:
$store = Cache::store('redis'); // Uses Laravel's RedisStore
$cachePool = new IlluminateCachePool($store);
Tag-Based Caching: Laravel’s tagging system is fully supported. Use tags for hierarchical cache invalidation:
// Store with tags
$item = $cachePool->getItem('user:123:profile');
$item->set('profile_data');
$cachePool->save($item, ['users', 'user:123']);
// Delete by tag
$cachePool->deleteByTag('users'); // Invalidates all items tagged 'users'
Integration with PSR-6 Consumers: Pass the adapter to any PSR-6-compliant library (e.g., Doctrine, Symfony):
$doctrineCache = new Doctrine\Common\Cache\Psr6\CacheItemPool($cachePool);
Dependency Injection: Register the adapter in Laravel’s service container for easy access:
$app->bind(\Psr\Cache\CacheItemPoolInterface::class, function ($app) {
return new IlluminateCachePool(Cache::store('redis'));
});
Fallback to Native Laravel Cache:
For operations not supported by PSR-6 (e.g., Cache::remember), use Laravel’s cache directly:
$value = Cache::remember('key', 60, function () {
return 'fallback_value';
});
Migration from Native Laravel Cache:
Cache::get('key') with $cachePool->getItem('key')->get().Cache::tags(['tag1', 'tag2'])->put('key', 'value') with:
$item = $cachePool->getItem('key');
$item->set('value');
$cachePool->save($item, ['tag1', 'tag2']);
Testing:
Use ArrayStore for in-memory testing:
$store = new ArrayStore();
$cachePool = new IlluminateCachePool($store);
// Test with $cachePool
Performance Tuning:
Benchmark the adapter against native PSR-6 drivers (e.g., predis/predis) for critical paths:
$start = microtime(true);
$cachePool->getItem('key')->get();
$time = microtime(true) - $start;
Leverage Laravel’s Cache Events:
Subscribe to Laravel’s cache events (e.g., CacheStoredEvent) for logging or analytics:
Cache::store('redis')->extend(function ($store) {
$store->extend('logging', function ($connection) {
$connection->listen(function ($event) {
Log::debug('Cache event: ' . $event->key);
});
});
return $store;
});
Combine with Other Adapters:
Use cache/adapter-common for advanced features like cache warming or fallback strategies:
use Cache\Adapter\Common\CacheItemPool;
$pool = new CacheItemPool($cachePool);
Custom Store Configuration: Extend the adapter to support custom store configurations:
class CustomStore extends FileStore {
public function __construct(array $options = []) {
parent::__construct($options + ['path' => storage_path('app/cache')]);
}
}
$store = new CustomStore();
$cachePool = new IlluminateCachePool($store);
Tagging Limitations:
FileStore does not). Validate driver compatibility before use.RedisStore or DatabaseStore for tagging.Missing PSR-6 Methods:
has() (PSR-6 1.1+). Polyfill it if needed:
$hasItem = $cachePool->getItem('key')->isHit();
Error Handling:
try-catch:
try {
$cachePool->getItem('key')->get();
} catch (\Exception $e) {
Log::error('Cache error: ' . $e->getMessage());
// Fallback logic
}
Performance Overhead:
$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {
$cachePool->getItem("key_$i")->get();
}
$time = microtime(true) - $start;
Laravel Version Mismatch:
Log Adapter Calls: Enable Laravel’s cache logging to debug issues:
Cache::store('redis')->extend(function ($store) {
$store->extend('logging', function ($connection) {
$connection->listen(function ($event) {
Log::debug('Cache event: ' . $event->key . ' | Action: ' . $event->action);
});
});
return $store;
});
Check Store Configuration:
Ensure the underlying store (e.g., Redis) is configured correctly in config/cache.php:
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
Validate Tagging: Verify tags are applied correctly:
$tags = $cachePool->getItem('key')->getTags();
dd($tags); // Should return ['tag1', 'tag2']
Environment-Specific Stores: Use Laravel’s environment-specific cache configurations:
$store = Cache::store(env('CACHE_DRIVER', 'file'));
$cachePool = new IlluminateCachePool($store);
Custom Cache Prefix: Laravel’s cache prefix may interfere with PSR-6 keys. Override it if needed:
$store = Cache::store('redis');
$store->setPrefix('myapp_');
$cachePool = new IlluminateCachePool($store);
Custom Cache Item:
Extend the adapter to support custom CacheItem implementations:
class CustomCacheItem extends \Cache\Adapter\Illuminate\IlluminateCacheItem {
public function getMetadata() {
return ['custom' => 'metadata'];
}
}
// Override the adapter's getItem method to use CustomCacheItem
Add Cache Statistics: Extend the adapter to collect and expose cache statistics:
class StatsCachePool extends IlluminateCachePool {
private $hits = 0;
private $misses = 0;
public function getItem($key) {
$item = parent::getItem($key);
if ($item->isHit()) {
$this->hits++;
} else {
$this->misses++;
}
return $item;
}
public function getStats() {
return ['hits' => $this->hits, 'misses' => $this->misses];
}
}
Support Additional Drivers:
Extend the adapter to support unsupported drivers (e.g., MemcachedStore):
class MemcachedCachePool extends IlluminateCachePool {
public function __construct(\Illuminate\Cache\MemcachedStore $store) {
parent::__construct($store);
}
// Override methods to handle Memcached-specific behavior
}
ArrayStore for Testing:
Replace Redis or databaseHow can I help you explore Laravel packages today?