@@ -31,6 +31,14 @@ trait MemcachedTrait
31
31
\Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_PHP ,
32
32
];
33
33
34
+ /**
35
+ * We are replacing characters that are illegal in Memcached keys with reserved characters from
36
+ * {@see \Symfony\Contracts\Cache\ItemInterface::RESERVED_CHARACTERS} that are legal in Memcached.
37
+ * Note: don’t use {@see \Symfony\Component\Cache\Adapter\AbstractAdapter::NS_SEPARATOR}.
38
+ */
39
+ private static $ RESERVED_MEMCACHED = " \n\r\t\v\f\0" ;
40
+ private static $ RESERVED_PSR6 = '@()\{}/ ' ;
41
+
34
42
private $ marshaller ;
35
43
private $ client ;
36
44
private $ lazyClient ;
@@ -235,7 +243,7 @@ protected function doSave(array $values, int $lifetime)
235
243
236
244
$ encodedValues = [];
237
245
foreach ($ values as $ key => $ value ) {
238
- $ encodedValues [rawurlencode ($ key )] = $ value ;
246
+ $ encodedValues [self :: encodeKey ($ key )] = $ value ;
239
247
}
240
248
241
249
return $ this ->checkResultCode ($ this ->getClient ()->setMulti ($ encodedValues , $ lifetime )) ? $ failed : false ;
@@ -247,13 +255,13 @@ protected function doSave(array $values, int $lifetime)
247
255
protected function doFetch (array $ ids )
248
256
{
249
257
try {
250
- $ encodedIds = array_map ('rawurlencode ' , $ ids );
258
+ $ encodedIds = array_map ('self::encodeKey ' , $ ids );
251
259
252
260
$ encodedResult = $ this ->checkResultCode ($ this ->getClient ()->getMulti ($ encodedIds ));
253
261
254
262
$ result = [];
255
263
foreach ($ encodedResult as $ key => $ value ) {
256
- $ result [rawurldecode ($ key )] = $ this ->marshaller ->unmarshall ($ value );
264
+ $ result [self :: decodeKey ($ key )] = $ this ->marshaller ->unmarshall ($ value );
257
265
}
258
266
259
267
return $ result ;
@@ -267,7 +275,7 @@ protected function doFetch(array $ids)
267
275
*/
268
276
protected function doHave ($ id )
269
277
{
270
- return false !== $ this ->getClient ()->get (rawurlencode ($ id )) || $ this ->checkResultCode (\Memcached::RES_SUCCESS === $ this ->client ->getResultCode ());
278
+ return false !== $ this ->getClient ()->get (self :: encodeKey ($ id )) || $ this ->checkResultCode (\Memcached::RES_SUCCESS === $ this ->client ->getResultCode ());
271
279
}
272
280
273
281
/**
@@ -276,7 +284,7 @@ protected function doHave($id)
276
284
protected function doDelete (array $ ids )
277
285
{
278
286
$ ok = true ;
279
- $ encodedIds = array_map ('rawurlencode ' , $ ids );
287
+ $ encodedIds = array_map ('self::encodeKey ' , $ ids );
280
288
foreach ($ this ->checkResultCode ($ this ->getClient ()->deleteMulti ($ encodedIds )) as $ result ) {
281
289
if (\Memcached::RES_SUCCESS !== $ result && \Memcached::RES_NOTFOUND !== $ result ) {
282
290
$ ok = false ;
@@ -322,4 +330,14 @@ private function getClient(): \Memcached
322
330
323
331
return $ this ->client = $ this ->lazyClient ;
324
332
}
333
+
334
+ private static function encodeKey (string $ key ): string
335
+ {
336
+ return strtr ($ key , self ::$ RESERVED_MEMCACHED , self ::$ RESERVED_PSR6 );
337
+ }
338
+
339
+ private static function decodeKey (string $ key ): string
340
+ {
341
+ return strtr ($ key , self ::$ RESERVED_PSR6 , self ::$ RESERVED_MEMCACHED );
342
+ }
325
343
}
0 commit comments