cache/memcache-adapter
PSR-6 cache pool implementation backed by the Memcache extension. Create a Memcache client, connect to your server, and use MemcacheCachePool for standards-based caching. Part of the PHP Cache (php-cache) ecosystem.
composer require cache/memcache-adapter
config/cache.php):
'stores' => [
'memcache' => [
'driver' => 'memcache',
'connection' => 'memcache',
'prefix' => 'laravel_',
],
],
.env:
CACHE_CONNECTIONS_memcache_driver=memcache
CACHE_CONNECTIONS_memcache_host=127.0.0.1
CACHE_CONNECTIONS_memcache_port=11211
Cache::extend('memcache', function ($app) {
$memcache = new \Memcache();
$memcache->connect(env('MEMCACHE_HOST', '127.0.0.1'), env('MEMCACHE_PORT', 11211));
return new \Cache\MemcacheAdapter\MemcacheCachePool($memcache);
});
Cache::put('key', 'value', now()->addMinutes(10));
$value = Cache::get('key');
// In a controller or service
$response = Cache::remember('api_users', now()->addHours(1), function () {
return Http::get('https://api.example.com/users')->json();
});
return response()->json($response);
Leverage Memcache’s tagging for bulk invalidation (e.g., user-specific cache):
// Store with tags
Cache::tags(['user:123'])->put('user_profile_123', $profileData, now()->addHours(1));
// Invalidate by tag (e.g., after user update)
Cache::tags(['user:123'])->flush();
Listen for model events to invalidate cache:
// In EventServiceProvider
protected $listen = [
'App\Events\UserUpdated' => [
'CacheInvalidationHandler',
],
];
// Handler
public function handle(UserUpdated $event) {
Cache::tags(['user:' . $event->user->id])->flush();
}
Combine Memcache (for hot data) with Redis (for persistence):
// In config/cache.php
'stores' => [
'memcache' => [
'driver' => 'memcache',
'connection' => 'memcache',
],
'redis' => [
'driver' => 'redis',
'connection' => 'redis',
],
],
// In a service
public function getData() {
$data = Cache::store('memcache')->get('hot_data');
if (!$data) {
$data = Cache::store('redis')->get('fallback_data');
}
return $data;
}
Reuse Memcache connections for efficiency:
// In a service provider
public function boot() {
$memcache = new \Memcache();
$memcache->connect(env('MEMCACHE_HOST'), env('MEMCACHE_PORT'));
Cache::extend('memcache', function () use ($memcache) {
return new \Cache\MemcacheAdapter\MemcacheCachePool($memcache);
});
}
Use PSR-6’s getItems() and deleteItems() for bulk operations:
// Get multiple items
$items = Cache::many(['key1', 'key2', 'key3']);
// Delete multiple items
Cache::forget(['key1', 'key2']);
Extension Dependency:
ext-memcache (not memcached). Verify availability:
php -m | grep memcache
ext-memcached or advocate for migration to Redis.Tagging Limitations:
Cache::tags() may not work out-of-the-box. Implement a wrapper:
Cache::extend('memcache', function () {
$pool = new MemcacheCachePool(new \Memcache());
return new class($pool) implements \Illuminate\Contracts\Cache\TaggableStore {
// Implement tagging methods
};
});
Serialization Issues:
serialize()/unserialize() or store references.Connection Failures:
Cache::remember('key', now()->addMinutes(5), function () {
return withRetry(3, function () {
return $expensiveOperation();
});
});
TTL Granularity:
now()->addMinutes() may lose precision.Cache::put('key', 'value', ceil(now()->addMinutes(10)->timestamp));
Inspect the Underlying Pool:
$pool = Cache::store('memcache')->getStore();
var_dump($pool->getItem('key')->isHit());
Check Memcache Stats:
$memcache = Cache::store('memcache')->getStore()->getClient();
var_dump($memcache->getStats());
Enable Memcache Logging:
$memcache = new \Memcache();
$memcache->setOption(\Memcache::OPT_DEBUG, 3);
Prefix Collisions:
laravel_) doesn’t conflict with other apps sharing the Memcache instance.config/cache.php.Case Sensitivity:
Cache::put('UserProfile', $data); // Avoid 'userprofile'
Default TTL:
null TTL (forever) may not work as expected. Use 0 for no expiration:
Cache::put('key', 'value', 0); // No expiration
Custom Cache Item:
Override MemcacheCacheItem for custom serialization:
class CustomMemcacheItem extends \Cache\MemcacheAdapter\MemcacheCacheItem {
public function get() {
$data = parent::get();
return json_decode($data, true);
}
}
Pool Decorator:
Add middleware to the MemcacheCachePool:
$pool = new MemcacheCachePool($memcache);
$pool = new class($pool) implements \Psr\Cache\CacheItemPoolInterface {
public function getItem($key) {
$item = $this->pool->getItem($key);
// Add custom logic (e.g., logging, compression)
return $item;
}
// Delegate other methods to $this->pool
};
Fallback Mechanism: Implement a fallback to another cache store:
Cache::extend('memcache_fallback', function () {
$memcachePool = new MemcacheCachePool(new \Memcache());
$redisPool = new \Cache\RedisAdapter\RedisCachePool(new \Redis());
return new class($memcachePool, $redisPool) implements \Psr\Cache\CacheItemPoolInterface {
public function getItem($key) {
try {
return $this->memcachePool->getItem($key);
} catch (\Exception $e) {
return $this->redisPool->getItem($key);
}
}
// Implement other methods
};
});
Connection Pooling: Reuse the Memcache connection across requests to avoid overhead:
// In a singleton service
public function getCachePool() {
static $pool;
if (!$pool) {
$memcache = new \Memcache();
$memcache->connect(env('MEMCACHE_HOST'), env('MEMCACHE_PORT'));
$pool = new MemcacheCachePool($memcache);
}
return $pool;
}
Compress Large Data:
Use gzip for large cache values:
Cache::put('key', gzcompress($data), now()->addHours(1));
// Retrieve
$data = gzuncompress(Cache::get('key'));
Avoid Blocking Calls: Offload cache
How can I help you explore Laravel packages today?