CakePHP 3: find() with cache

人盡茶涼 提交于 2019-12-05 18:55:51

The query builder doesn't suport caching via options, it has a separate method that is to be used, Query::cache(), which you'd use like

$query = $table->find();
$query->cache('cache_key');

$query->cache('cache_key', 'configName');

$query->cache(function($query) {
    return md5(
        serialize($query->clause('select')) .
        serialize($query->clause('where'))
    );
});

// ...

See

get() supports caching via an option as that's the only way to configure the internal find call, since it's being executed immediately so that get() can return throw possible errors and return an entity.

I have investigated cakephp 3 documentation and other resources for good example of using cache() with queries, but didn't found any (docs gives only short snipped, not full example)

I have very similar problem with my method in my model /src/Model/Table/MetaTagTable.php

namespace App\Model\Table;

use Cake\ORM\Table;

class MetaTagTable extends Table
{
    /**
     * Get meta tags from db table
     * 
     * @return array
     */
    function getMetaTags($controller, $action, $hasSearchParamFlag)
    {
        $hasSearchParamFlag = (int) $hasSearchParamFlag;

        return $this
            ->find()
            ->select(['tag', 'type'])
            ->where(
                [
                    'controller'=> $controller,
                    'action'=> $action,
                    'have_search_param'=> $hasSearchParamFlag,
                ]
            )
            ->all()
            ->cache(
                function () use ($controller, $action, $hasSearchParamFlag) 
                {
                    return "getMetaTags-$controller, $action, $hasSearchParamFlag";
                },
                'middle'
            );
    }
}

The above example shows me a fatal error:

Error: Call to undefined method Cake\ORM\ResultSet::cache()  

the official cakephp 3 doc doesn't give a full example, about how cache() with query builder works, so using @ndm answer and trying several different variants of code I made my code working, just moving cache() call before ->all() method calling:

function getMetaTags($controller, $action, $hasSearchParamFlag)
{
    $hasSearchParamFlag = (int) $hasSearchParamFlag;

    return $this
        ->find()
        ->select(['tag', 'type'])
        ->where(
            [
                'controller'=> $controller,
                'action'=> $action,
                'have_search_param'=> $hasSearchParamFlag,
            ]
        )                              
        ->cache(
            function () use ($controller, $action, $hasSearchParamFlag) 
            {
                return "getMetaTags-$controller, $action, $hasSearchParamFlag";
            },
            'middle'
        )                        
        ->all()
        ->toArray();
}

because cache() method belongs to a trait "QueryTrait", and cache() method need to be called for Cake\ORM\Query class, not for Cake\ORM\ResultSet.

Now all working, enjoy!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!