Skip to content

[Cache] ChainAdapter accepts CacheItemPoolInterface, so it should work with adapter of CacheItemPoolInterface other than \Symfony\Component\Cache\Adapter\AdapterInterface #60160

Closed
@PatchRanger

Description

@PatchRanger

Symfony version(s) affected

7.*

Description

ChainAdapter accepts list of CacheItemPoolInterface.
It makes me assuming that I can use it together with either AdapterInterface or any external class implementing CacheItemPoolInterface.
If I got it correct, I can do such thing in my DI as CacheItemPoolInterface:

new ChainAdapter(
  adapters: [
    new \Symfony\Component\Cache\Adapter\ArrayAdapter(storeSerialized: false),
    YiiHelper::get(\Yii2Extended\Yii2Cache\Psr6ToYii2Cache::class), // it implements CacheItemPoolInterface
  ],
);

But I can't. It leads to the TypeError (see below in Additonal context).

How to reproduce

I've created a minimal script to reproduce. it's attached.
reproducer.php.txt

Here's the text of the script, if that's more convenient.

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Symfony\Component\Cache\Adapter\ChainAdapter;
use Yii2Extended\Yii2Cache\Psr6ToYii2Cache;

$chainAdapter = new ChainAdapter(
    adapters: [
        new \Symfony\Component\Cache\Adapter\ArrayAdapter(storeSerialized: false),
        new Psr6ToYii2Cache(new \yii\caching\ArrayCache()),
    ],
);

$cacheKey = 'foo';
$item = $chainAdapter->getItem($cacheKey);
if ($item->isHit()) {
    echo 'isHit', "\n";
    echo $item->get(), "\n";
}
$item->set('bar');

echo 'before save', "\n";
$chainAdapter->save($item);
echo 'after save', "\n";

In place of the Psr6ToYii2Cache can be any external (i.e., not implementing the \Symfony\Component\Cache\Adapter\AdapterInterface) class that implements the CacheItemPoolInterface.

Possible Solution

I've fixed it locally by such fix:
vendor/symfony/cache/CacheItem.php

- protected ?ItemInterface $innerItem = null;
+ protected ?\Psr\Cache\CacheItemInterface $innerItem = null;

In my view it's adequate: as long as ChainAdapter accepts CacheItemPoolInterface, it's normal that innerItem should be of CacheItemInterface.

Additional Context

reproducer.php without fix leads to such error message:

PHP Fatal error: Uncaught TypeError: Cannot assign Yii2Extended\Yii2Cache\Psr6ToYii2CacheItem to property Symfony\Component\Cache\CacheItem::$innerItem of type ?Symfony\Contracts\Cache\ItemInterface in /code/vendor/symfony/cache/Adapter/ProxyAdapter.php:60

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions