CakePHP 3: find() with cache

好久不见. 提交于 2019-12-22 09:25:46

问题


About the get() method, I read here:

Like find() get has caching integrated. You can use the cache option when calling get() to perform read-through caching

But later, in the section dedicated to the find() method (here), the cache is not mentioned, there are no examples for the cache and the cache option is not mentioned among the supported options.

So I would like to know: can I use the cache option with the find() method? If so, how?

Thanks.


Thanks to ndm. So:

$query = $this->Pages->find('all');
$query->cache('all_pages');

$this->set('pages', $query->all());

Or (more simple):

$query = $this->Pages->find('all')->cache('all_pages');

$this->set('pages', $query->all());

回答1:


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

  • Cookbook > Query Builder > Caching Loaded Results
  • \Cake\Datasource\QueryTrait::cache()

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.




回答2:


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!



来源:https://stackoverflow.com/questions/29696575/cakephp-3-find-with-cache

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