Symfony Cache Component - Redis Adapter

1.9k Views Asked by At

I have implemented the Symfony Cache Component using RedisAdapter. Now we like to use a colon as separator in cache keys (e.g. some:cache:key:25). Just like Redis recommends.

I get an Exception saying "contains reserved characters {}()/\@: etc.". This is explained in Symfony Documentation

(https://symfony.com/doc/3.4/components/cache/cache_items.html) that those are reserved characters in PSR-6.

I like to know if there is a way around that? Because i am busy refactoring cache logic using Symfony Cache Component. But keys are already defined, so i am not able to change them without breaking conventions.

2

There are 2 best solutions below

2
dbrumann On

As you noted : is a reserved character in the PSR-6 cache standard, which Symfony's cache component builds on.

If you want to keep them in your code, you could write an adapter that takes your keys and replaces the : with something else before passing it to the regular cache.

So for example you could write an adapter that looks something like this:

class MyCacheAdapter implements AdapterInterface
{
    private $decoratedAdapter;

    public function __construct(AdapterInterface $adapter)
    {
        $this->decoratedAdapter = $adapter;
    }

    public function getItem($key): CacheItemInterface
    {
        $key = str_replace(':', '.', $key);

        return $this->decoratedAdapter->getItem($key);
    }

    ...
}

For all other methods you can just proxy the call to the decorated service and return the result. It's a bit annoying to write, but the interface demands it.

In your service configuration you can configure it like this:

services:
    App\Cache\MyCacheAdapter:
        decorates: 'Symfony\Component\Cache\Adapter\RedisAdapter'
        arguments:
            $adapter: '@app.cache.adapter.redis'

This configuration is only a rough outline both argument and the class names might have to be adjusted. In any case with this service decoration your adapter wraps around the original redis adapter and then when you configure it to be used by the cache component it should work fine, that your existing keys like some:cache:key25 will be converted to some.cache.key25 before they are passed into the cache component, so before the error message happens.

0
Eugene Kaurov On

In addition to the @dbrumann reply: semicolon is not the only character that is reserved. ItemInterface::RESERVED_CHARACTERS has a full list. Other approaches to make cache key safe:

$cacheKey = str_replace(str_split(ItemInterface::RESERVED_CHARACTERS), '-', $str);

or simpler

$cacheKey = hash('crc32b', $str);