leaseweb/memcache-bundle
Deprecated Symfony bundle adding Memcache (php-memcache) integration for sessions and caching, including Doctrine support and Web Debug Toolbar profiling to analyze cache behavior and performance under high load. Not actively maintained; consider forking.
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require leaseweb/memcache-bundle
Add to AppKernel.php:
new Lsw\MemcacheBundle\LswMemcacheBundle(),
Basic Configuration (config.yml):
lsw_memcache:
pools:
default:
servers:
- { host: localhost, tcp_port: 11211 }
First Use Case: Inject the Memcache client in a controller/service:
use Lsw\MemcacheBundle\Client\MemcacheClientInterface;
public function __construct(MemcacheClientInterface $memcache)
{
$this->memcache = $memcache;
}
public function cacheExample()
{
$this->memcache->set('key', 'value', 0, 3600); // 1 hour TTL
$value = $this->memcache->get('key');
}
session.pool in config (see Session Support).doctrine.metadata_cache, doctrine.result_cache, or doctrine.query_cache.// Set with TTL (0 = no expiration)
$this->memcache->set('user:123:profile', $profileData, 0, 3600);
// Get with fallback
$profileData = $this->memcache->get('user:123:profile') ?: $this->loadFromDb();
// Delete
$this->memcache->delete('user:123:profile');
// Increment/Decrement (e.g., for counters)
$this->memcache->increment('hit_counter', 1);
// Atomic read-modify-write to prevent stampedes
$oldValue = $this->memcache->getAdp('expensive:calc:123');
if ($oldValue === false) {
$newValue = $this->expensiveCalculation();
$this->memcache->setAdp('expensive:calc:123', $newValue, 0, 3600);
} else {
// Use stale data if available
}
# config.yml
lsw_memcache:
session:
pool: sessions
locking: true # Critical for multi-server setups
spin_lock_wait: 150000 # 150ms lock retry interval
# services.yml
my.session.handler:
class: Lsw\MemcacheBundle\Session\Storage\LockingSessionHandler
arguments:
- "@memcache.sessions" # Your configured pool service
- { prefix: "app_sess_", expiretime: 7200 }
# config.yml
lsw_memcache:
doctrine:
metadata_cache:
pool: default
entity_manager: default
result_cache:
pool: default
entity_manager: [default, read_replica]
prefix: "result:"
query_cache:
pool: default
entity_manager: default
// Enable result caching for a query
$query->useResultCache(true);
$query->setCacheLifetime(300); // 5 minutes
# config.yml
lsw_memcache:
firewall:
pool: firewall
concurrency: 50 # Max 50 concurrent requests per IP
reverse_proxies: [10.0.0.1, 10.0.0.2] # Trusted proxies
$this->get('lsw_memcache.firewall')->isAllowed($request->getClientIp());
# config.yml
lsw_memcache:
pools:
primary:
servers: [{ host: memcache1, port: 11211 }]
secondary:
servers: [{ host: memcache2, port: 11211 }]
options:
redundancy: true
session_redundancy: 2
$pool = $this->get('memcache.primary'); // Inject via DI
if ($pool->isDown()) {
$pool = $this->get('memcache.secondary');
}
| Issue | Solution |
|---|---|
| Session data missing in Profiler | Sessions are written after page render; use session_write_close() early. |
| Connection failures | Enable allow_failover: true and monitor max_failover_attempts. |
| Stale ADP data | ADP may return old values during race conditions; design for eventual consistency. |
| Memory bloat | Set compress_threshold (e.g., 20000) to compress large values. |
| PHP 7+ compatibility | Use pecl-memcache for PHP 7. |
Memcache tab for hit/miss ratios, latency, and memory usage.php app/console lsw:memcache:stats
# config.yml
lsw_memcache:
pools:
default:
options:
log_errors: true
| Parameter | Recommendation |
|---|---|
chunk_size |
Increase (e.g., 65536) for large objects. |
hash_strategy |
Use consistent for multi-server setups. |
session_redundancy |
Set to 2 for high-availability sessions. |
lock_timeout |
Reduce (e.g., 5) for faster session locks in high-concurrency apps. |
// services.yml
my.custom.memcache:
class: MyApp\CustomMemcacheClient
arguments:
- "@memcache.default"
tags:
- { name: lsw_memcache.client, alias: custom }
// Subscribe to cache events
use Lsw\MemcacheBundle\Event\MemcacheEvents;
public function onCacheMiss(MemcacheMissEvent $event) {
if ($event->getKey() === 'expensive:calc') {
$event->setValue($this->fallbackCalculation());
}
}
memcached extension: This bundle requires the memcache extension (not memcached).config/packages/lsw_memcache.yaml instead of config.yml.entity_manager names match your Doctrine config.ttl (even if 0 for "no expiration").get()/set() in request paths.user:123:profile) to avoid collisions.!tagged for complex structures.| Use Case | Alternative Bundle |
|---|---|
| Redis Support | snc/redis-bundle |
| Modern Memcached | predis/predis (with `php-m |
How can I help you explore Laravel packages today?