Skip to content

Commit df1c2a1

Browse files
Support for phpredis 6.x (#6209)
Co-authored-by: 李铭昕 <[email protected]>
1 parent 104366a commit df1c2a1

File tree

3 files changed

+78
-28
lines changed

3 files changed

+78
-28
lines changed

src/RedisConnection.php

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use Redis;
2323
use RedisCluster;
2424
use RedisException;
25-
use RedisSentinel;
2625
use Throwable;
2726

2827
/**
@@ -230,36 +229,28 @@ protected function createRedisSentinel(): Redis
230229
$readTimeout = $this->config['sentinel']['read_timeout'] ?? 0;
231230
$masterName = $this->config['sentinel']['master_name'] ?? '';
232231
$auth = $this->config['sentinel']['auth'] ?? null;
233-
// fixes bug for phpredis
234-
// https://github.com/phpredis/phpredis/issues/2098
235-
$extendConfig = [];
236-
if (! empty($auth)) {
237-
$extendConfig[] = $auth;
238-
}
239232

240233
shuffle($nodes);
241234

242235
$host = null;
243236
$port = null;
244237
foreach ($nodes as $node) {
245238
try {
246-
$nodeUrlArray = parse_url($node);
247-
$sentinelHost = $nodeUrlArray['host'] ?? null;
248-
$sentinelPort = $nodeUrlArray['port'] ?? null;
249-
if (! $sentinelHost || ! $sentinelPort) {
239+
$resolved = parse_url($node);
240+
if (! isset($resolved['host'], $resolved['port'])) {
250241
$this->log(sprintf('The redis sentinel node [%s] is invalid.', $node), LogLevel::ERROR);
251242
continue;
252243
}
253-
254-
$sentinel = new RedisSentinel(
255-
$sentinelHost,
256-
intval($sentinelPort),
257-
$timeout,
258-
$persistent,
259-
$retryInterval,
260-
$readTimeout,
261-
...$extendConfig
262-
);
244+
$options = [
245+
'host' => $resolved['host'],
246+
'port' => (int) $resolved['port'],
247+
'connectTimeout' => $timeout,
248+
'persistent' => $persistent,
249+
'retryInterval' => $retryInterval,
250+
'readTimeout' => $readTimeout,
251+
...($auth ? ['auth' => $auth] : []),
252+
];
253+
$sentinel = $this->container->get(RedisSentinelFactory::class)->create($options);
263254
$masterInfo = $sentinel->getMasterAddrByName($masterName);
264255
if (is_array($masterInfo) && count($masterInfo) >= 2) {
265256
[$host, $port] = $masterInfo;

src/RedisSentinelFactory.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* This file is part of Hyperf.
6+
*
7+
* @link https://www.hyperf.io
8+
* @document https://hyperf.wiki
9+
* @contact [email protected]
10+
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
11+
*/
12+
namespace Hyperf\Redis;
13+
14+
use RedisSentinel;
15+
16+
class RedisSentinelFactory
17+
{
18+
protected bool $isOlderThan6 = false;
19+
20+
public function __construct()
21+
{
22+
$this->isOlderThan6 = version_compare(phpversion('redis'), '6.0.0', '<');
23+
}
24+
25+
public function create(array $options = []): RedisSentinel
26+
{
27+
if ($this->isOlderThan6) {
28+
return new RedisSentinel(
29+
$options['host'],
30+
(int) $options['port'],
31+
(float) $options['connectTimeout'],
32+
$options['persistent'],
33+
(int) $options['retryInterval'],
34+
(float) $options['readTimeout'],
35+
...(isset($options['auth']) ? [$options['auth']] : []),
36+
);
37+
}
38+
39+
// https://github.com/phpredis/phpredis/blob/develop/sentinel.md#examples-for-version-60-or-later
40+
return new RedisSentinel($options); /* @phpstan-ignore-line */
41+
}
42+
}

tests/RedisTest.php

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@
4545
*/
4646
class RedisTest extends TestCase
4747
{
48+
protected bool $isOlderThan6 = false;
49+
50+
protected function setUp(): void
51+
{
52+
$this->isOlderThan6 = version_compare(phpversion('redis'), '6.0.0', '<');
53+
}
54+
4855
protected function tearDown(): void
4956
{
5057
Mockery::close();
@@ -60,7 +67,11 @@ public function testRedisConnect()
6067
$this->assertSame('host', $host->getName());
6168
$this->assertSame('port', $port->getName());
6269
$this->assertSame('timeout', $timeout->getName());
63-
$this->assertSame('retry_interval', $retryInterval->getName());
70+
if ($this->isOlderThan6) {
71+
$this->assertSame('retry_interval', $retryInterval->getName());
72+
} else {
73+
$this->assertSame('persistent_id', $retryInterval->getName());
74+
}
6475

6576
$this->assertTrue($redis->connect('127.0.0.1', 6379, 0.0, null, 0, 0));
6677
}
@@ -155,14 +166,16 @@ public function testRedisClusterConstructor()
155166
$ref = new ReflectionClass(RedisCluster::class);
156167
$method = $ref->getMethod('__construct');
157168
$names = [
158-
'name', 'seeds', 'timeout', 'read_timeout', 'persistent', 'auth',
169+
'name', 'seeds', 'timeout', 'read_timeout', 'persistent', 'auth', 'context',
159170
];
160171
foreach ($method->getParameters() as $parameter) {
161172
$this->assertSame(array_shift($names), $parameter->getName());
162173
if ($parameter->getName() === 'seeds') {
163174
$this->assertSame('array', $parameter->getType()->getName());
164175
} else {
165-
$this->assertNull($parameter->getType());
176+
if ($this->isOlderThan6) {
177+
$this->assertNull($parameter->getType());
178+
}
166179
}
167180
}
168181
}
@@ -198,11 +211,15 @@ public function testRedisSentinelParams()
198211
$rel = new ReflectionClass(RedisSentinel::class);
199212
$method = $rel->getMethod('__construct');
200213
$count = count($method->getParameters());
201-
if ($count === 6) {
202-
$this->markTestIncomplete('RedisSentinel don\'t support auth.');
203-
}
214+
if ($this->isOlderThan6) {
215+
if ($count === 6) {
216+
$this->markTestIncomplete('RedisSentinel don\'t support auth.');
217+
}
204218

205-
$this->assertSame(7, $count);
219+
$this->assertSame(7, $count);
220+
} else {
221+
$this->assertSame(1, $count);
222+
}
206223
}
207224

208225
private function getRedis()

0 commit comments

Comments
 (0)