symfony/cache
Symfony Cache is a fast, low-overhead caching component with PSR-6 implementations and adapters for common backends. Includes a PSR-16 adapter plus support for symfony/cache-contracts CacheInterface and TagAwareCacheInterface.
To start using symfony/cache in Laravel, install the package via Composer:
composer require symfony/cache
Leverage the CacheInterface for a simple in-memory cache:
use Symfony\Component\Cache\Adapter\ArrayAdapter;
// Create a basic cache instance
$cache = new ArrayAdapter();
// Store and retrieve data
$cache->set('key', 'value', 3600); // 1 hour TTL
$value = $cache->get('key'); // 'value'
Configure Redis via Laravel's cache config (config/cache.php) and use the adapter:
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Psr16Cache;
$redisClient = new \Redis();
$redisClient->connect('127.0.0.1', 6379);
$cache = new RedisAdapter($redisClient, 'laravel_cache', 0);
$psr16Cache = new Psr16Cache($cache); // PSR-16 wrapper
For database-backed caching:
use Symfony\Component\Cache\Adapter\DoctrineDbalAdapter;
use Doctrine\DBAL\Connection;
$connection = // Your DBAL connection;
$cache = new DoctrineDbalAdapter($connection, 'laravel_cache', 0);
Use CacheInterface for low-level cache operations:
// Store with TTL
$cache->save($item, $key, new \DateInterval('PT1H'));
// Get with fallback
$value = $cache->get($key, function() {
return computeExpensiveValue();
});
// Delete and clear
$cache->delete($key);
$cache->clear();
Wrap PSR-6 cache in Psr16Cache for simplicity:
$psr16Cache = new Psr16Cache($cache);
$psr16Cache->set('key', 'value', 3600); // TTL in seconds
$value = $psr16Cache->get('key');
Use TagAwareAdapter for grouped cache invalidation:
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
// Create a tag-aware cache
$tagAwareCache = new TagAwareAdapter($cache, 'product_');
// Store with tags
$tagAwareCache->save($item, 'product_123', new \DateInterval('PT1H'));
$tagAwareCache->getTags()->add('product_123');
// Invalidate by tag
$tagAwareCache->invalidateTags(['product_123']);
Combine multiple caches (e.g., Redis + Filesystem):
use Symfony\Component\Cache\Adapter\ChainAdapter;
$redisCache = new RedisAdapter($redisClient, 'redis_', 0);
$fileCache = new FilesystemAdapter('/path/to/cache', 'file_', 0);
$chainCache = new ChainAdapter([$redisCache, $fileCache]);
Prevent race conditions with LockFactory:
use Symfony\Component\Cache\Lock\LockFactory;
$lockFactory = new LockFactory($cache);
$lock = $lockFactory->createLock('unique_lock_key', 10); // 10-second TTL
if ($lock->acquire()) {
try {
// Critical section
} finally {
$lock->release();
}
}
Extend Laravel's cache manager:
// config/cache.php
'stores' => [
'symfony_redis' => [
'driver' => 'symfony',
'adapter' => 'redis',
'connection' => 'default',
'prefix' => 'laravel_',
],
],
// In a service provider
Cache::extend('symfony', function ($app) {
$redis = Redis::connection('default');
return new RedisAdapter($redis, 'laravel_', 0);
});
_/:. Invalid prefixes (e.g., /) will throw exceptions.
// Valid
$cache = new RedisAdapter($redis, 'laravel_', 0);
// Invalid (throws exception)
$cache = new RedisAdapter($redis, 'laravel/', 0);
dev_, prod_).TagAwareAdapter explicitly.TagAwareAdapter or use AbstractTagAwareAdapter.ChainAdapter stops at the first successful cache hit (no fallback to next adapter if the first fails).ChainAdapter with a fast cache (e.g., APCu) first, followed by a persistent cache (e.g., Redis).// Bad: Risk of deadlock
$lock->acquire(true); // Block forever
// Good: Timeout after 10 seconds
$lock->acquire(false, 10);
LockFactory with LockInterface for distributed locking (e.g., Redis, DBAL).// Fails
$cache->set('key', $nonSerializableObject);
// Solution: Serialize manually
$cache->set('key', serialize($object));
Symfony\Component\Serializer\SerializerInterface for complex objects.// Sets TTL to 1 hour (3600 seconds)
$cache->save($item, 'key', new \DateInterval('PT1H'));
RedisAdapter with RedisClusterAdapter for high availability:
$redisCluster = new \RedisCluster();
$cache = new RedisClusterAdapter($redisCluster, 'cluster_', 0);
CacheItem::isHit() to check if a cache item was found:
$item = $cache->getItem('key');
if (!$item->isHit()) {
$item->set(expensiveOperation());
$cache->save($item);
}
ArrayAdapter for development (fast, in-memory) and switch to RedisAdapter/DoctrineDbalAdapter for production.ApcuAdapter (if APCu is available).CacheItem::expiresAfter() with short TTLs for sensitive data:
$item->expiresAfter(60); // 1 minute
AbstractAdapter or AbstractTagAwareAdapter.use Symfony\Component\Cache\Adapter\AbstractAdapter;
class LoggingAdapter extends AbstractAdapter {
public function get($key, $default = null) {
\Log::debug("Cache hit for key: {$key}");
return parent::get($key, $default);
}
}
How can I help you explore Laravel packages today?