yii2 icon indicating copy to clipboard operation
yii2 copied to clipboard

Using `yii\caching\CallbackDependency::$callback` as closure causes "Serialization of 'Closure' is not allowed" exception

Open xcopy opened this issue 7 months ago • 3 comments

All following dependencies failed:

$d1 = new \yii\caching\CallbackDependency(['callback' => fn () => Yii::$app->user->identity->getId()]);
$d2 = new \yii\caching\CallbackDependency(['callback' => [Yii::$app->user->identity, 'getAuthKey']]),
$d3 = new \yii\caching\ChainedDependency([
    'dependencies' => [
        $d1,
        $d2,
        new \yii\caching\DbDependency(['sql' => 'select max(created_time) from "user"']),
    ]
]);

if ($this->beginCache('users', ['dependency' => ...])) {
    // cached content here
    $this->endCache();
}

The exception: Serialization of 'Closure' is not allowed

in in vendor/yiisoft/yii2/caching/Cache.php

Image

However, static and function callbacks (obviously) work as expected:

$d1 = new \yii\caching\CallbackDependency(['callback' => ['foo', 'bar']]);
$d2 = new \yii\caching\CallbackDependency(['callback' => 'foo::bar']);
$d3 = new \yii\caching\CallbackDependency(['callback' => 'foobar']);

xcopy avatar May 09 '25 08:05 xcopy

Yes. That is the current limitation. Any way to overcome it that you think about?

samdark avatar May 11 '25 14:05 samdark

How about this:

class CallbackDependency extends Dependency
{
    // ...

    public function __serialize()
    {
        return get_class_vars(self::class);
    }
}

which will return

O:30:"yii\caching\CallbackDependency":3:{s:8:"callback";N;s:4:"data";N;s:8:"reusable";b:0;}

And yeah, gotta to think about how to implement __unserialize().

Wys guys? Am I digging in the right direction?

xcopy avatar May 11 '25 15:05 xcopy

Kind of yes. But deserializing is the hard part in this case. We can add serialization of closures support, there are multiple solutions, but I'm not sure if it could be simpler and if it worth it.

samdark avatar May 15 '25 12:05 samdark