@@ -75,6 +75,10 @@ public function __construct(array $configuration, array $connectionCredentials =
75
75
}
76
76
77
77
$ initializer = static function ($ redis ) use ($ host , $ port , $ auth , $ serializer , $ dbIndex ) {
78
+ if (null === $ redis ) {
79
+ $ redis = !is_array ($ host ) ? new \Redis () : new \RedisCluster (null , $ host );
80
+ }
81
+
78
82
if ($ redis instanceof \Redis) {
79
83
$ redis ->connect ($ host , $ port );
80
84
}
@@ -89,17 +93,13 @@ public function __construct(array $configuration, array $connectionCredentials =
89
93
throw new InvalidArgumentException ('Redis connection failed: ' .$ redis ->getLastError ());
90
94
}
91
95
92
- return true ;
96
+ return $ redis ;
93
97
};
94
98
95
- if (null === $ redis ) {
96
- $ redis = new \Redis ();
97
- }
98
-
99
99
if ($ configuration ['lazy ' ] ?? self ::DEFAULT_OPTIONS ['lazy ' ]) {
100
100
$ redis = new RedisProxy ($ redis , $ initializer );
101
101
} else {
102
- $ initializer ($ redis );
102
+ $ redis = $ initializer ($ redis );
103
103
}
104
104
105
105
$ this ->connection = $ redis ;
@@ -122,20 +122,25 @@ public function __construct(array $configuration, array $connectionCredentials =
122
122
$ this ->claimInterval = $ configuration ['claim_interval ' ] ?? self ::DEFAULT_OPTIONS ['claim_interval ' ];
123
123
}
124
124
125
- public static function fromDsn (string $ dsn , array $ redisOptions = [], \Redis $ redis = null ): self
125
+ /**
126
+ * @param \Redis|\RedisCluster|null $redis
127
+ */
128
+ public static function fromDsn (string $ dsn , array $ redisOptions = [], $ redis = null ): self
126
129
{
127
- $ url = $ dsn ;
130
+ if (false === strpos ($ dsn , ', ' )) {
131
+ $ parsedUrl = self ::parseDsn ($ dsn , $ redisOptions );
132
+ } else {
133
+ $ parsedUrls = array_map (function ($ dsn ) use (&$ redisOptions ) {
134
+ return self ::parseDsn ($ dsn , $ redisOptions );
135
+ }, explode (', ' , $ dsn ));
128
136
129
- if (preg_match ('#^redis:///([^:@])+$# ' , $ dsn )) {
130
- $ url = str_replace ('redis: ' , 'file: ' , $ dsn );
131
- }
137
+ // Merge all the URLs, the last one overrides the previous ones
138
+ $ parsedUrl = array_merge (...$ parsedUrls );
132
139
133
- if (false === $ parsedUrl = parse_url ($ url )) {
134
- throw new InvalidArgumentException (sprintf ('The given Redis DSN "%s" is invalid. ' , $ dsn ));
135
- }
136
- if (isset ($ parsedUrl ['query ' ])) {
137
- parse_str ($ parsedUrl ['query ' ], $ dsnOptions );
138
- $ redisOptions = array_merge ($ redisOptions , $ dsnOptions );
140
+ // Regroup all the hosts in an array interpretable by RedisCluster
141
+ $ parsedUrl ['host ' ] = array_map (function ($ parsedUrl ) {
142
+ return $ parsedUrl ['host ' ] . ': ' . ($ parsedUrl ['port ' ] ?? 6379 );
143
+ }, $ parsedUrls );
139
144
}
140
145
141
146
self ::validateOptions ($ redisOptions );
@@ -227,6 +232,25 @@ public static function fromDsn(string $dsn, array $redisOptions = [], \Redis $re
227
232
return new self ($ configuration , $ connectionCredentials , $ redisOptions , $ redis );
228
233
}
229
234
235
+ private static function parseDsn (string $ dsn , array &$ redisOptions ): array
236
+ {
237
+ $ url = $ dsn ;
238
+
239
+ if (preg_match ('#^redis:///([^:@])+$# ' , $ dsn )) {
240
+ $ url = str_replace ('redis: ' , 'file: ' , $ dsn );
241
+ }
242
+
243
+ if (false === $ parsedUrl = parse_url ($ url )) {
244
+ throw new InvalidArgumentException (sprintf ('The given Redis DSN "%s" is invalid. ' , $ dsn ));
245
+ }
246
+ if (isset ($ parsedUrl ['query ' ])) {
247
+ parse_str ($ parsedUrl ['query ' ], $ dsnOptions );
248
+ $ redisOptions = array_merge ($ redisOptions , $ dsnOptions );
249
+ }
250
+
251
+ return $ parsedUrl ;
252
+ }
253
+
230
254
private static function validateOptions (array $ options ): void
231
255
{
232
256
$ availableOptions = array_keys (self ::DEFAULT_OPTIONS );
0 commit comments