Using `yii\caching\CallbackDependency::$callback` as closure causes "Serialization of 'Closure' is not allowed" exception
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
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']);
Yes. That is the current limitation. Any way to overcome it that you think about?
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?
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.