diff --git a/CHANGELOG.md b/CHANGELOG.md index e8dee44..a415741 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 7.0.0 +- (CHG) `RedisSessionHandler` now requires Redis 4.0 or later. `PhpredisClient::del()` no longer falls back to `DEL` when `UNLINK` is unavailable, and `PredisClient::del()` uses `UNLINK` too, so both adapters behave the same. The fallback could not be reached by any supported server, so it was untestable dead weight. - (ADD) Add `RedisSessionHandler`, an optional `SessionHandlerInterface` implementation that stores each session as a single Redis string with a key TTL (the approach used by Symfony, Laravel, and the phpredis native handler). It refreshes only the TTL when data is unchanged (`lazy_write`), destroys empty sessions, and leaves expiry to Redis. It is decoupled from any specific client via `Aura\Session\Redis\RedisClientInterface`, with bundled `PhpredisClient` (ext-redis) and `PredisClient` (predis/predis) adapters. No hard Redis-client dependency: `ext-redis` and `predis/predis` are listed under `suggest`. - (ADD) Add `Segment::getFlashAll()` and `Segment::getFlashNextAll()`, which return every flash value for the current or the next request, so flash messages can be rendered without knowing their keys. Both return an empty array when nothing is set. Originally proposed by Jake Johns in #47/#52. - (ADD) Depend on the new `aura/session-interface` (`^7.0`) package, which provides the shared session/segment contracts. diff --git a/docs/getting-started.md b/docs/getting-started.md index 237ed8b..c86d8c8 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -241,6 +241,9 @@ The handler is decoupled from any specific Redis client through - `Aura\Session\Redis\PhpredisClient` — for the [phpredis](https://github.com/phpredis/phpredis) extension (`ext-redis`). - `Aura\Session\Redis\PredisClient` — for the [predis/predis](https://github.com/predis/predis) package. +Redis 4.0 or later is required: the handler deletes keys with `UNLINK`, so the +memory is reclaimed in a background thread rather than blocking the server. + You can also implement `RedisClientInterface` yourself to back the handler with another client. diff --git a/src/Redis/PhpredisClient.php b/src/Redis/PhpredisClient.php index 1ec9386..b2ca568 100644 --- a/src/Redis/PhpredisClient.php +++ b/src/Redis/PhpredisClient.php @@ -55,14 +55,9 @@ public function setEx(string $key, int $ttl, string $value): void public function del(string $key): void { - // UNLINK reclaims memory in a background thread; fall back to DEL on - // servers older than Redis 4.0. - if (method_exists($this->redis, 'unlink')) { - $this->redis->unlink($key); - return; - } - - $this->redis->del($key); + // UNLINK reclaims memory in a background thread. It needs Redis 4.0, + // which is older than the PHP version this package requires. + $this->redis->unlink($key); } public function expire(string $key, int $ttl): void diff --git a/src/Redis/PredisClient.php b/src/Redis/PredisClient.php index f3b73e3..35f8a24 100644 --- a/src/Redis/PredisClient.php +++ b/src/Redis/PredisClient.php @@ -54,7 +54,9 @@ public function setEx(string $key, int $ttl, string $value): void public function del(string $key): void { - $this->redis->del([$key]); + // UNLINK reclaims memory in a background thread. It needs Redis 4.0, + // which is older than the PHP version this package requires. + $this->redis->unlink([$key]); } public function expire(string $key, int $ttl): void diff --git a/src/Redis/RedisClientInterface.php b/src/Redis/RedisClientInterface.php index 9f8279f..47a9710 100644 --- a/src/Redis/RedisClientInterface.php +++ b/src/Redis/RedisClientInterface.php @@ -48,7 +48,8 @@ public function setEx(string $key, int $ttl, string $value): void; /** * - * Deletes $key. + * Deletes $key, using UNLINK so the memory is reclaimed in a background + * thread. This needs Redis 4.0 or later. * * @param string $key The Redis key. *