Skip to content

PSR16::getMultiple returns invalid value #58632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
JoniJnm opened this issue Oct 22, 2024 · 11 comments
Open

PSR16::getMultiple returns invalid value #58632

JoniJnm opened this issue Oct 22, 2024 · 11 comments

Comments

@JoniJnm
Copy link

JoniJnm commented Oct 22, 2024

Symfony version(s) affected

7.1.2

Description

PSR16::getMultiple is not returning the expected value when the adapter is a TagAwareAdapter

Instead of the value, it's returning a instance of ValueWrapped

How to reproduce

$adapter = new TagAwareAdapter(new ArrayAdapter());
$cache = new Psr16Cache($adapter);
$cache->set('k', 'v');

// ok => v
$value = $cache->get('k');

// not ok, a ValueWrapped object (©)
// expected value: ['k' => 'v']
$value = $cache->getMultiple(['k']);

Possible Solution

I'm not sure what's the solution, but in the following code:

https://github.com/symfony/cache/blob/7.1/CacheItem.php#L165-L173

because it's a tagAware there is a key with empty "tags", and that's why it's returning a ValueWrapped

In https://github.com/symfony/cache/blob/7.1/Psr16Cache.php#L150, removing the ! it also works (so just returning $item->get())

Additional Context

No response

@JoniJnm JoniJnm added the Bug label Oct 22, 2024
@xabbuh xabbuh added the Cache label Oct 22, 2024
@JoniJnm JoniJnm changed the title PSR16::getMultiple invalid value PSR16::getMultiple returns invalid value Oct 22, 2024
@xabbuh
Copy link
Member

xabbuh commented Oct 23, 2024

Can you test if #58639 would fix it for you?

@JoniJnm
Copy link
Author

JoniJnm commented Oct 23, 2024

@xabbuh yes, with that code it works

@xabbuh
Copy link
Member

xabbuh commented Oct 23, 2024

Unfortunately the solution is not that simple as this change now breaks other things.

@nicolas-grekas
Copy link
Member

Maybe you shouldn't decorate this way: the TagAwareAdapter in between is of no use with PSR-16.

I think there might be conflicting expectations here: IIRC, the current code is meant to allow tags to work through PSR-16/16 (aka being able to use a PSR-6/16 storage that'd work with tags).

Not every decoration order is supposed to work.

@JoniJnm
Copy link
Author

JoniJnm commented Oct 23, 2024

why the get function is not taking into account the metadata but getMultiple is?

@nicolas-grekas
Copy link
Member

That's good point, we might be a bit light on this topic, test cases are missing for sure, that'd document the use cases and prevent regressions.

@xabbuh
Copy link
Member

xabbuh commented Oct 23, 2024

When I was working on the patch I was in fact wondering if our way of returning metadata (in some cases) in getMultiple() is actually conform with PSR16. On the other hand as the failing tests in #58639 show without them writing an adapter for the other direction becomes harder (impossible?).

@JoniJnm
Copy link
Author

JoniJnm commented Oct 23, 2024

In my opinion, the MR is ok and the problem is in Psr16Adapter

The failing tests is due that adapter. I think the adapter should wrap the value into an object to support metadata. And always unwrap it again. So the wrap is done in that adapter and not in PSR16Cache.

@carsonbot
Copy link

Hey, thanks for your report!
There has not been a lot of activity here for a while. Is this bug still relevant? Have you managed to find a workaround?

@JoniJnm
Copy link
Author

JoniJnm commented Apr 24, 2025

Hi, in my opinion is still relevant.

The How to reproduce section is still failing (using symfony 7.2.5)

My workaround was map the values:

    public function getMultiple(iterable $keys, mixed $default = null): iterable
    {
        $data = $this->cache->getMultiple($keys, $default);

        return self::fixGetMultiple($data);
    }

    public static function fixGetMultiple(iterable $data): iterable
    {
        // https://github.com/symfony/symfony/issues/58632
        $wrapperClass = "\xA9";

        if (false === class_exists($wrapperClass)) {
            return $data;
        }

        return map(
            static function (mixed $value) use ($wrapperClass) {
                if ($value instanceof $wrapperClass) {
                    return $value->value;
                }

                return $value;
            },
            $data,
        );
    }

@carsonbot carsonbot removed the Stalled label Apr 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants