From d69f7c2118e00bcbfbdb8fde48a7fb2196af7f1a Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 6 Nov 2025 12:19:34 +0100 Subject: [PATCH] re-allow ext-redis 6.1 --- composer.json | 2 +- src/Symfony/Component/Cache/CHANGELOG.md | 2 +- .../Cache/Traits/Redis62ProxyTrait.php | 52 +++++++++++++++++++ .../Cache/Traits/RedisCluster62ProxyTrait.php | 47 +++++++++++++++++ .../Cache/Traits/RedisClusterProxy.php | 21 +------- .../Component/Cache/Traits/RedisProxy.php | 26 +--------- .../Component/Cache/Traits/RedisTrait.php | 4 +- src/Symfony/Component/Cache/composer.json | 2 +- .../Messenger/Bridge/Redis/CHANGELOG.md | 2 +- .../Bridge/Redis/Transport/Connection.php | 9 +++- .../Messenger/Bridge/Redis/composer.json | 2 +- 11 files changed, 115 insertions(+), 54 deletions(-) create mode 100644 src/Symfony/Component/Cache/Traits/Redis62ProxyTrait.php create mode 100644 src/Symfony/Component/Cache/Traits/RedisCluster62ProxyTrait.php diff --git a/composer.json b/composer.json index 41ab14fab3b5a..b8ae634a14d1b 100644 --- a/composer.json +++ b/composer.json @@ -170,7 +170,7 @@ }, "conflict": { "ext-psr": "<1.1|>=2", - "ext-redis": "<6.2", + "ext-redis": "<6.1", "ext-relay": "<0.12.1", "amphp/amp": "<2.5", "async-aws/core": "<1.5", diff --git a/src/Symfony/Component/Cache/CHANGELOG.md b/src/Symfony/Component/Cache/CHANGELOG.md index fb3016acbdc11..8b0c2b7e7faa5 100644 --- a/src/Symfony/Component/Cache/CHANGELOG.md +++ b/src/Symfony/Component/Cache/CHANGELOG.md @@ -4,7 +4,7 @@ CHANGELOG 7.4 --- - * Bump ext-redis to 6.2 and ext-relay to 0.12 minimum + * Bump ext-redis to 6.1 and ext-relay to 0.12 minimum 7.3 --- diff --git a/src/Symfony/Component/Cache/Traits/Redis62ProxyTrait.php b/src/Symfony/Component/Cache/Traits/Redis62ProxyTrait.php new file mode 100644 index 0000000000000..d29466cbb92c5 --- /dev/null +++ b/src/Symfony/Component/Cache/Traits/Redis62ProxyTrait.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +if (version_compare(phpversion('redis'), '6.2.0', '>=')) { + /** + * @internal + */ + trait Redis62ProxyTrait + { + public function expiremember($key, $field, $ttl, $unit = null): \Redis|false|int + { + return $this->initializeLazyObject()->expiremember(...\func_get_args()); + } + + public function expirememberat($key, $field, $timestamp): \Redis|false|int + { + return $this->initializeLazyObject()->expirememberat(...\func_get_args()); + } + + public function getWithMeta($key): \Redis|array|false + { + return $this->initializeLazyObject()->getWithMeta(...\func_get_args()); + } + + public function serverName(): false|string + { + return $this->initializeLazyObject()->serverName(...\func_get_args()); + } + + public function serverVersion(): false|string + { + return $this->initializeLazyObject()->serverVersion(...\func_get_args()); + } + } +} else { + /** + * @internal + */ + trait Redis62ProxyTrait + { + } +} diff --git a/src/Symfony/Component/Cache/Traits/RedisCluster62ProxyTrait.php b/src/Symfony/Component/Cache/Traits/RedisCluster62ProxyTrait.php new file mode 100644 index 0000000000000..e96dee46d2907 --- /dev/null +++ b/src/Symfony/Component/Cache/Traits/RedisCluster62ProxyTrait.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +if (version_compare(phpversion('redis'), '6.2.0', '>=')) { + /** + * @internal + */ + trait RedisCluster62ProxyTrait + { + public function expiremember($key, $field, $ttl, $unit = null): \Redis|false|int + { + return $this->initializeLazyObject()->expiremember(...\func_get_args()); + } + + public function expirememberat($key, $field, $timestamp): \Redis|false|int + { + return $this->initializeLazyObject()->expirememberat(...\func_get_args()); + } + + public function getdel($key): mixed + { + return $this->initializeLazyObject()->getdel(...\func_get_args()); + } + + public function getWithMeta($key): \RedisCluster|array|false + { + return $this->initializeLazyObject()->getWithMeta(...\func_get_args()); + } + } +} else { + /** + * @internal + */ + trait RedisCluster62ProxyTrait + { + } +} diff --git a/src/Symfony/Component/Cache/Traits/RedisClusterProxy.php b/src/Symfony/Component/Cache/Traits/RedisClusterProxy.php index 2cde053d1e1b3..6bedcfaf7f731 100644 --- a/src/Symfony/Component/Cache/Traits/RedisClusterProxy.php +++ b/src/Symfony/Component/Cache/Traits/RedisClusterProxy.php @@ -24,6 +24,7 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); */ class RedisClusterProxy extends \RedisCluster implements ResetInterface, LazyObjectInterface { + use RedisCluster62ProxyTrait; use RedisProxyTrait { resetLazyObject as reset; } @@ -273,16 +274,6 @@ public function expireat($key, $timestamp, $mode = null): \RedisCluster|bool return $this->initializeLazyObject()->expireat(...\func_get_args()); } - public function expiremember($key, $field, $ttl, $unit = null): \Redis|false|int - { - return $this->initializeLazyObject()->expiremember(...\func_get_args()); - } - - public function expirememberat($key, $field, $timestamp): \Redis|false|int - { - return $this->initializeLazyObject()->expirememberat(...\func_get_args()); - } - public function expiretime($key): \RedisCluster|false|int { return $this->initializeLazyObject()->expiretime(...\func_get_args()); @@ -353,21 +344,11 @@ public function get($key): mixed return $this->initializeLazyObject()->get(...\func_get_args()); } - public function getWithMeta($key): \RedisCluster|array|false - { - return $this->initializeLazyObject()->getWithMeta(...\func_get_args()); - } - public function getbit($key, $value): \RedisCluster|false|int { return $this->initializeLazyObject()->getbit(...\func_get_args()); } - public function getdel($key): mixed - { - return $this->initializeLazyObject()->getdel(...\func_get_args()); - } - public function getex($key, $options = []): \RedisCluster|false|string { return $this->initializeLazyObject()->getex(...\func_get_args()); diff --git a/src/Symfony/Component/Cache/Traits/RedisProxy.php b/src/Symfony/Component/Cache/Traits/RedisProxy.php index 6c75c9ad646cc..7e99b606f7889 100644 --- a/src/Symfony/Component/Cache/Traits/RedisProxy.php +++ b/src/Symfony/Component/Cache/Traits/RedisProxy.php @@ -24,6 +24,7 @@ class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class); */ class RedisProxy extends \Redis implements ResetInterface, LazyObjectInterface { + use Redis62ProxyTrait; use RedisProxyTrait { resetLazyObject as reset; } @@ -273,16 +274,6 @@ public function expireAt($key, $timestamp, $mode = null): \Redis|bool return $this->initializeLazyObject()->expireAt(...\func_get_args()); } - public function expiremember($key, $field, $ttl, $unit = null): \Redis|false|int - { - return $this->initializeLazyObject()->expiremember(...\func_get_args()); - } - - public function expirememberat($key, $field, $timestamp): \Redis|false|int - { - return $this->initializeLazyObject()->expirememberat(...\func_get_args()); - } - public function expiretime($key): \Redis|false|int { return $this->initializeLazyObject()->expiretime(...\func_get_args()); @@ -448,11 +439,6 @@ public function getTransferredBytes(): array return $this->initializeLazyObject()->getTransferredBytes(...\func_get_args()); } - public function getWithMeta($key): \Redis|array|false - { - return $this->initializeLazyObject()->getWithMeta(...\func_get_args()); - } - public function getset($key, $value): \Redis|false|string { return $this->initializeLazyObject()->getset(...\func_get_args()); @@ -913,16 +899,6 @@ public function select($db): \Redis|bool return $this->initializeLazyObject()->select(...\func_get_args()); } - public function serverName(): false|string - { - return $this->initializeLazyObject()->serverName(...\func_get_args()); - } - - public function serverVersion(): false|string - { - return $this->initializeLazyObject()->serverVersion(...\func_get_args()); - } - public function set($key, $value, $options = null): \Redis|bool|string { return $this->initializeLazyObject()->set(...\func_get_args()); diff --git a/src/Symfony/Component/Cache/Traits/RedisTrait.php b/src/Symfony/Component/Cache/Traits/RedisTrait.php index 918336a700696..97233ed0c5b95 100644 --- a/src/Symfony/Component/Cache/Traits/RedisTrait.php +++ b/src/Symfony/Component/Cache/Traits/RedisTrait.php @@ -193,7 +193,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra } if (isset($params['sentinel']) && !class_exists(\Predis\Client::class) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) { - throw new CacheException('Redis Sentinel support requires one of: "predis/predis", "ext-redis >= 5.2", "ext-relay".'); + throw new CacheException('Redis Sentinel support requires one of: "predis/predis", "ext-redis >= 6.1", "ext-relay".'); } foreach (['lazy', 'persistent', 'cluster'] as $option) { @@ -224,7 +224,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra }; if (isset($params['sentinel']) && !is_a($class, \Predis\Client::class, true) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) { - throw new CacheException(\sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and neither ext-redis >= 5.2 nor ext-relay have been found.', $class)); + throw new CacheException(\sprintf('Cannot use Redis Sentinel: class "%s" does not extend "Predis\Client" and neither ext-redis >= 6.1 nor ext-relay have been found.', $class)); } $isRedisExt = is_a($class, \Redis::class, true); diff --git a/src/Symfony/Component/Cache/composer.json b/src/Symfony/Component/Cache/composer.json index e5834e9fbd29f..c8280d55549a6 100644 --- a/src/Symfony/Component/Cache/composer.json +++ b/src/Symfony/Component/Cache/composer.json @@ -43,7 +43,7 @@ "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "conflict": { - "ext-redis": "<6.2", + "ext-redis": "<6.1", "ext-relay": "<0.12.1", "doctrine/dbal": "<3.6", "symfony/dependency-injection": "<6.4", diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/CHANGELOG.md b/src/Symfony/Component/Messenger/Bridge/Redis/CHANGELOG.md index fe19b620056af..fb2f1eeeb811e 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/CHANGELOG.md +++ b/src/Symfony/Component/Messenger/Bridge/Redis/CHANGELOG.md @@ -4,7 +4,7 @@ CHANGELOG 7.4 --- - * Bump ext-redis to 6.2 and ext-relay to 0.12 minimum + * Bump ext-redis to 6.1 and ext-relay to 0.12 minimum 7.3 --- diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php index 3e4d3231c644e..5b18bd2c9f346 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php +++ b/src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php @@ -79,7 +79,7 @@ public function __construct(array $options, \Redis|Relay|\RedisCluster|null $red $sentinelMaster = $options['sentinel'] ?? $options['redis_sentinel'] ?? $options['sentinel_master'] ?? null; if (null !== $sentinelMaster && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) { - throw new InvalidArgumentException('Redis Sentinel support requires ext-redis>=5.2, or ext-relay.'); + throw new InvalidArgumentException('Redis Sentinel support requires ext-redis>=6.1, or ext-relay.'); } if (null !== $sentinelMaster && $redis instanceof \RedisCluster) { @@ -697,6 +697,7 @@ public function getMessageCount(): int } // Iterate through the stream. See https://redis.io/commands/xrange/#iterating-a-stream. + $useExclusiveRangeInterval = version_compare(phpversion('redis'), '6.2.0', '>='); $total = 0; while (true) { if (!$range = $redis->xRange($this->stream, $lastDeliveredId, '+', 100)) { @@ -705,7 +706,11 @@ public function getMessageCount(): int $total += \count($range); - $lastDeliveredId = preg_replace_callback('#\d+$#', static fn (array $matches) => (int) $matches[0] + 1, array_key_last($range)); + if ($useExclusiveRangeInterval) { + $lastDeliveredId = preg_replace_callback('#\d+$#', static fn (array $matches) => (int) $matches[0] + 1, array_key_last($range)); + } else { + $lastDeliveredId = '('.array_key_last($range); + } } } diff --git a/src/Symfony/Component/Messenger/Bridge/Redis/composer.json b/src/Symfony/Component/Messenger/Bridge/Redis/composer.json index a1d17a472b1cf..aee4d1722b27f 100644 --- a/src/Symfony/Component/Messenger/Bridge/Redis/composer.json +++ b/src/Symfony/Component/Messenger/Bridge/Redis/composer.json @@ -26,7 +26,7 @@ "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "conflict": { - "ext-redis": "<6.2", + "ext-redis": "<6.1", "ext-relay": "<0.12" }, "autoload": {