1

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
  • Can you share the full and exact error message? Commented Oct 19, 2018 at 8:28
  • 1
    Read this onwards please. There is a bug label attached to it. Commented Oct 19, 2018 at 14:57

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

i like that approach. thanks a lot. the thing is, people at my place like to have colon in the keys, so that redis clients work correctly (e.g. list redis values as directory folder). but perhaps i have to discuss further with my team.
In that case, if you want to keep the colon in redis as well, you have to write your own adapter that does not extend the AbstractAdapter and that ignores the validation check. If you look at the AbstractAdapter you should see where the exception is thrown and then replace the closures used to perform the check. It might be that other places in the cache component need adjustment as well for that.
0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.