Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cache Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

To start using symfony/cache in Laravel, install the package via Composer:

composer require symfony/cache

First Use Case: Basic PSR-6 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'

First Use Case: Redis Cache (Production)

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

First Use Case: Doctrine DBAL Cache

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);

Implementation Patterns

1. PSR-6 Cache Integration

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();

2. PSR-16 Cache (Simple Key-Value)

Wrap PSR-6 cache in Psr16Cache for simplicity:

$psr16Cache = new Psr16Cache($cache);
$psr16Cache->set('key', 'value', 3600); // TTL in seconds
$value = $psr16Cache->get('key');

3. Tag-Aware Caching

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']);

4. Chaining Adapters

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]);

5. Locking Mechanism

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();
    }
}

6. Laravel-Specific Integration

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);
});

Gotchas and Tips

1. Prefix Handling

  • Gotcha: Prefixes must be alphanumeric or contain _/:. Invalid prefixes (e.g., /) will throw exceptions.
    // Valid
    $cache = new RedisAdapter($redis, 'laravel_', 0);
    
    // Invalid (throws exception)
    $cache = new RedisAdapter($redis, 'laravel/', 0);
    
  • Tip: Use consistent prefixes across environments (e.g., dev_, prod_).

2. Tag-Aware Cache Quirks

  • Gotcha: Tags are not automatically synced across chained adapters. Use TagAwareAdapter explicitly.
  • Tip: For complex tagging, implement a custom TagAwareAdapter or use AbstractTagAwareAdapter.

3. ChainAdapter Behavior

  • Gotcha: ChainAdapter stops at the first successful cache hit (no fallback to next adapter if the first fails).
  • Tip: Use ChainAdapter with a fast cache (e.g., APCu) first, followed by a persistent cache (e.g., Redis).

4. Locking Pitfalls

  • Gotcha: Locks do not block indefinitely. Always set a TTL to avoid deadlocks.
    // Bad: Risk of deadlock
    $lock->acquire(true); // Block forever
    
    // Good: Timeout after 10 seconds
    $lock->acquire(false, 10);
    
  • Tip: Use LockFactory with LockInterface for distributed locking (e.g., Redis, DBAL).

5. Serialization Issues

  • Gotcha: Non-serializable objects (e.g., closures, resources) cannot be cached.
    // Fails
    $cache->set('key', $nonSerializableObject);
    
    // Solution: Serialize manually
    $cache->set('key', serialize($object));
    
  • Tip: Use Symfony\Component\Serializer\SerializerInterface for complex objects.

6. Redis-Specific Tips

  • Gotcha: Redis TTL is set in seconds, not milliseconds.
    // Sets TTL to 1 hour (3600 seconds)
    $cache->save($item, 'key', new \DateInterval('PT1H'));
    
  • Tip: Use RedisAdapter with RedisClusterAdapter for high availability:
    $redisCluster = new \RedisCluster();
    $cache = new RedisClusterAdapter($redisCluster, 'cluster_', 0);
    

7. Debugging Cache Issues

  • Tip: Enable Symfony's debug toolbar to inspect cache hits/misses.
  • Tip: Use CacheItem::isHit() to check if a cache item was found:
    $item = $cache->getItem('key');
    if (!$item->isHit()) {
        $item->set(expensiveOperation());
        $cache->save($item);
    }
    

8. Performance Optimization

  • Tip: Use ArrayAdapter for development (fast, in-memory) and switch to RedisAdapter/DoctrineDbalAdapter for production.
  • Tip: For high write throughput, consider ApcuAdapter (if APCu is available).

9. Security Considerations

  • Gotcha: Never cache sensitive data (e.g., passwords, tokens) unless encrypted.
  • Tip: Use CacheItem::expiresAfter() with short TTLs for sensitive data:
    $item->expiresAfter(60); // 1 minute
    

10. Extending the Cache

  • Tip: Create custom adapters by extending AbstractAdapter or AbstractTagAwareAdapter.
  • Example: Custom cache with logging:
    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);
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/graphviz
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata