Yii2: Cache - Serialization of 'Closure' is not allowed

Created on 18 Mar 2015  路  12Comments  路  Source: yiisoft/yii2

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?

Most helpful comment

Yes it is.
Convert this anonymous function into the model internal method.

All 12 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sobit picture sobit  路  3Comments

MUTOgen picture MUTOgen  路  3Comments

Kolyunya picture Kolyunya  路  3Comments

skcn022 picture skcn022  路  3Comments

indicalabs picture indicalabs  路  3Comments