在 CakePHP 中对搜索结果进行分页

Posted

技术标签:

【中文标题】在 CakePHP 中对搜索结果进行分页【英文标题】:Paginate a search result in CakePHP 【发布时间】:2012-12-01 11:58:52 【问题描述】:

我在我的 Cakephp 项目中设置了一个简单的搜索引擎,看起来像这样:

<?php 
    echo $this->Form->create("Post", array(
        "action" => "search", 
        "id" => "searchForm"
    ));
    echo $this->Form->input("keyword", array(
        "label" => "",
        "type" => "search",
        "placeholder" => "Recherche..."
    ));
    echo $this->Form->end(); 
?>

这是控制器:

function search() 
    $keyword = $this->request->data;
    $keyword = $keyword["Post"]["keyword"];
    $cond = array("OR" => array(
        "Post.title LIKE '%$keyword%'",
        "Post.description LIKE '%$keyword%'"
    ));
    $posts = $this->Post->find("all", array("conditions" => $cond));
    $this->set(compact("posts", "keyword"));

而且效果很好。唯一的问题是当我想对结果进行分页时。我只是添加:

$posts = $this->paginate();

这就是问题所在。当我添加这个时,CakePHP 会给我所有的帖子,而不仅仅是那些与关键字匹配的帖子。

所以,如果你有一个解决方案,那就太好了:)

【问题讨论】:

你看过 cake dc 搜索插件了吗? github.com/cakedc/search 它以干净干爽的方式完成所有这些工作 - 您可以省去很多重新发明***的麻烦。 是的,这是我的第一个想法,但是,我不知道,它只是不想工作。或者我在设置时做错了什么...... 很可能是后者——因为它对我们大多数人来说都完美无缺:) 【参考方案1】:

根据 CakePHP 的书你应该可以做到

$this->paginate('Post', array(
    'OR' => array(
        'Post.title LIKE' => "%$keyword%",
        'Post.description LIKE' => "%$keyword%"
    )

));

或者你可以这样做(来自 cakephp 网站)。

public function list_recipes() 
    $this->paginate = array(
        'conditions' => array('Recipe.title LIKE' => 'a%'),
        'limit' => 10
    );
    $data = $this->paginate('Recipe');
    $this->set(compact('data'));
);

来源: http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html

【讨论】:

您的第一个解决方案是我首先尝试的。但是,当我这样做时,搜索时没有结果:/ 哦!似乎现在可以工作了。剩下的唯一问题是它看起来很奇怪,它似乎只在Post.description 中查找关键字。如果我搜索仅在标题中而不在描述中的单词,它将找不到。 它生成什么样的 SQL,它看起来是否正确?它会选择手术室吗? OR 似乎没问题,但它似乎不会转换 Post.title : SELECT Post.Post.@ 上的 $keyword 变量987654331@, ... WHERE ((Post.title LIKE '%$keyword%') OR (Post.description LIKE '%test%')) ORDER BY Post.created desc 限制 16` 伙计,今天不是我的日子。忘记了标题周围的双引号。再次编辑我的答案:-)【参考方案2】:

Paginate 对我相信的数据进行自己的查找。您之前调用的findpaginate 没有影响。

试试这个:

$this->paginate = array( 'conditions' => $cond, ));

【讨论】:

【参考方案3】:

您可以使用 Session 来存储条件 首先,当您提交表单时,您将条件存储到 Session 然后(分页)您可以从 Session

中读取条件
example i want to search the products:
Products/search.ctp
<?php
    echo $this->Form->create('Product');
    echo $this->Form->input('keyword');
    echo $this->Form->end(__('Search'));
?>
ProductsController.php
<?php 
class ProductsController extends AppController

public function search() 
        if ($this->request->is('post')) 
            $keyword = $this->request->data['Product']['keyword'];
            $this->paginate = array(
                'fields' => array('Product.name', 'Product.price', 'Product.created'),
                'order' => array('Product.created' => 'DESC', 'Product.price' => 'DESC'),
                'limit' => 30,
                'conditions' => array('Product.name LIKE' => '%' . $keyword . '%')
            );
            // store array $this->paginate into Session
            $this->Session->write('paginate', $this->paginate);
        
        $this->paginate = $this->Session->read('paginate');
        $this->set('products', $this->paginate('Product'));
    

【讨论】:

以上是关于在 CakePHP 中对搜索结果进行分页的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MongoDB 中对聚合查询结果进行分页并获得总文档数(Node.js + Mongoose)?

从分页的 CakePHP 控制器中找出有多少页的结果

cakephp弹性搜索分页

java在分页查询结果中对最后的结果集List进行操作add()或remove()操作,报错:java.lang.UnsupportedOperationException

在 has_many 上具有条件的 CakePHP 分页

如何删除或更改postgresql上的cakephp分页计数查询?