SRw*_*ebs 1 pagination caching cakephp cakephp-3.0
我需要在CakePHP 3分页搜索中缓存分页结果.
当我使用CakePHP 2.x时,我能够在appModel中覆盖paginate函数.使用新的CakePHP ORM可以获得相同的结果吗?因为$query->cache()在paginate查询对象中不起作用.
我已经阅读了关于这个主题的一些讨论,但如果可能的话我需要一个例子.
问题中没有显示代码,但我们假设您从一个简单的烘焙控制器索引操作开始:
public function index()
{
$this->set('posts', $this->paginate($this->Posts));
$this->set('_serialize', ['posts']);
}
Run Code Online (Sandbox Code Playgroud)
首先,要认识到控制器方法paginate 接受表或查询对象 - 如果传递了表对象,则paginator组件只需调用find来处理查询对象.所以,上面的代码在功能上等同于:
public function index()
{
$query = $this->Posts->find();
$this->set('posts', $this->paginate($query));
$this->set('_serialize', ['posts']);
}
Run Code Online (Sandbox Code Playgroud)
只需对上面的代码进行一些小修改就可以使用查询的缓存方法:
public function index()
{
$query = $this->Posts->find();
$cacheKey = $this->name . '_' . md5(json_encode($this->request->query));
$query->cache($cacheKey);
$this->set('posts', $this->paginate($query));
$this->set('_serialize', ['posts']);
}
Run Code Online (Sandbox Code Playgroud)
查询参数和控制器名称用于生成唯一的缓存键,以便一次调用paginate的缓存结果不会与另一个请求的调用混淆.
当以这种方式使用时仍将发出计数,如果这是一个问题,它仍然可以通过定义计数器回调来防止:
public function index()
{
$query = $this->Posts->find();
$cacheKey = $this->name . '_' . md5(json_encode($this->request->query));
$searchTerms = []; // define this
$countCacheKey = $this->name . '_' . md5(json_encode($searchTerms)) . '_count';
$query
->cache($cacheKey)
->counter(function($query) use ($countCacheKey) {
return Cache::remember($countCacheKey, function() use ($query) {
return $query->count();
});
});
$this->set('posts', $this->paginate($query));
$this->set('_serialize', ['posts']);
}
Run Code Online (Sandbox Code Playgroud)
即简单地将调用包装到count方法中Cache::remember.
请注意,答案中用于计数的缓存键对于所有请求都是相同的,因为在此示例中要分页的行数对于所有请求都是相同的.如果您要对搜索进行分页 - 例如,搜索条件应该用于计数缓存键.
| 归档时间: |
|
| 查看次数: |
1146 次 |
| 最近记录: |