I'm trying to cache simple query. Artist hasMany Song, Song->getArtist (with condition).
$mainArtist = Yii::$app->cache->get('get-main-artist-of-song_id-'.$this->id);
if ( $mainArtist === false ) {
$mainArtist = Artist::find()
->innerJoin('artist_song', 'artist_song.song_id = '.$this->id)
->one();
Yii::$app->cache->set('get-main-artist-of-song_id-'.$this->id, $mainArtist);
}
Result: Exception - Serialization of 'Closure' is not allowed
For "Query cache" i need to use DbDependency.
$dependency = new DbDependency;
$dependency->sql = '**????**';
$mainArtist = Artist::getDb()->cache( function($db) {
return Artist::find()
->innerJoin('artist_song', 'artist_song.song_id = '.$this->id)
->one();
}, null, $dependency);
What dependency do i need to use?
Anything that doesn't have closure.
samdark, where is closure in my code?
Give me please example of dependency in my case.
$dependency->sql = '**????**';
$mainArtist = Artist::getDb()->cache( function($db) { <---- here
Closure == anonymous function. These could not be serialized in PHP.
Ok, but i'm trying to set cache this data:
$mainArtist = Artist::find()
->innerJoin('artist_song', 'artist_song.song_id = '.$this->id)
->one();
Yii::$app->cache->set('get-main-artist-of-song_id-'.$this->id, $mainArtist);
There is no anonymous functions in my code, but i have got Exception - Serialization of 'Closure' is not allowed.
there might be a problem with the AR instance being cached. Could be that there is a closure bound as an event handler. @longmayar can you show your AR code? do you have any behaviors declared in the active record class?
class Artist extends ActiveRecord
{
...
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'created_at',
ActiveRecord::EVENT_BEFORE_UPDATE => 'updated_at',
],
'value' => function() { return date('Y-m-d H:i:s'); }
]
];
}
...
}
May be it's 'value' => function() { return date('Y-m-d H:i:s'); } ?
Yes it is.
Convert this anonymous function into the model internal method.
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'created_at',
ActiveRecord::EVENT_BEFORE_UPDATE => 'updated_at',
],
'value' => DateTimer::now()
]
];
}
Great!
samdark, cebe, klimov-paul, thanks a lot!
Oh.. this time i got warning on create new Artist:
call_user_func() expects parameter 1 to be a valid callback, function '18.03.2015 14:36:12' not found or invalid function name
Specify it as [$this, 'getNow'] and create a method getNow in the class.
It works! Thx
Yes it is.
Convert this anonymous function into the model internal method.
I had the same problem, and the @klimov-paul solution solved
Most helpful comment
Yes it is.
Convert this anonymous function into the model internal method.