cakePHP 使用 post 数据分页,无需会话、序列化或 post 来获取

Posted

技术标签:

【中文标题】cakePHP 使用 post 数据分页,无需会话、序列化或 post 来获取【英文标题】:cakePHP paginate with post data without sessions, serialization or post to get 【发布时间】:2011-02-25 00:19:34 【问题描述】:

我在控制器/索引中创建了一个带有 POST 操作的小型搜索和过滤表单,它向自身发布要分页的条件和字段 ($this->paginate($conditions))。

这对第一页来说是好的,但是在随后的页面上过滤条件会丢失。分页passedArgs 很好地支持 GET 变量。

是否有一种简单的方法可以将 POST 条件传递给其他分页页面?

我看过的方法是通过会话传递$conditions,这并非没有分配会话和取消再次提交表单时设置会话的复杂性(用户对过滤条件的更多改进) . 另一种方法是将$conditions 作为序列化字符串传递,url_encode 作为 GET 参数。

有没有像passedArgs 这样的“蛋糕”方式来做到这一点。 Sessions 和url_encode 看起来不像蛋糕风格。

谢谢

【问题讨论】:

【参考方案1】:

有没有简单的方法来传递 将条件发布到其他分页 页面?

没有。

有没有一个好的蛋糕方法来做到这一点 更像 passArgs、会话和 url 编码看起来不像蛋糕风格。

只有一种方法,不管蛋糕还是不蛋糕。

    必须使用 GET 方法进行搜索。

    通过 QUERY STRING 传递参数。

因此,使用 method="GET" 创建搜索表单,然后使用 http_build_query() 组合查询字符串并使用它来链接到其他页面。

有点好奇,你可以在这里看到一个例子:

http://***.com/questions/tagged?tagnames=php&page=5&sort=newest&pagesize=50

【讨论】:

【参考方案2】:

你可以使用passedArgs。

在方法控制器中:

if ( empty($this->passedArgs['search']) )
    $this->passedArgs['search'] = $this->data['YourModel']['search'];

if ( empty($this->data) )
    $this->data['YourModel']['search'] = $this->passedArgs['search'];

在你看来:

$this->Paginator->options(array('url' => $this->passedArgs));

【讨论】:

如果有人在,比如第 2 页,然后他们再次搜索,我在方法控制器中添加了一个额外的行来处理这个问题: if (!empty($this->passedArgs['page']) ) $this->redirect(array('search'=> $this->passedArgs['search'], 'page' => 1)); 【参考方案3】:

如果是我,我会按照您将内容保存到会话中的想法运行。然后我会在会话中添加一个页面维度来存储每个页面,从而使用户可以轻松地来回走动。

$this->Session->write('Search.page.1.params',$params);
$this->Session->write('Search.page.2.params',$params2);

为了以蛋糕的方式进行,您可能需要编写自己的分页助手或插件。然后你可以在你的控制器中更有效地使用它作为

$this->MyPages->paginate('MyModel');

我想,此功能还可以让您选择允许您的用户“保存我的搜索”(如果他们愿意),因为您可以将会话参数转储到 SavedSearch 模型或类似模型中。

在开始新搜索之前不要忘记$this->Session->destroy()

【讨论】:

只是为了获得更多可能对其他人有帮助的信息,下面是一个代码 sn-p 谷歌搜索基于会话的分页 if(!empty($this->data)) Sanitize::clean($这个->数据); $searchkey = $this->Session->read('Search.searchkey'); if(empty($searchkey)) $this->Session->write('Search.searchkey', $this->data['Search']['searchkey']); if($this->data['Search']['searchkey'] != $this->Session->read('Search.searchkey')) $this->Session->delete('Search.searchkey '); $this->Session->write('Search.searchkey', $this->data['Search']['searchkey']); 【参考方案4】:

您还可以使用Post/Redirect/Get design pattern 模式来解决这个问题,允许用户为搜索的 URL 添加书签(它们不会像会话那样过期)并保持 URL 看起来友好。例如:

function index($searchTerms = null) 
    // post/redirect/get
    if (isset($this->data['SearchForm'])) 
        $this->redirect(array($this->data['SearchForm']['search_terms']));
    
    // your normal code here.

搜索表单数据 POST 到 /controller/action,但用户被重定向,而是 GETs /controller/action/search+terms,其中术语作为参数传递到操作中(即$searchTerms)。

如果您只是将表单提交方法更改为 GET,您将看到类似:/controller/action?data[SearchForm][search_terms]=search+terms

【讨论】:

【参考方案5】:

感谢 Deizel 的 POST / REDIRECT / GET 模式。 我实现了发布数据的 GET 方法。 对于分页使用这个 $urlparams = $this->params['url'];unset($urlparams['url']); $paginator->options(array('url' => array('?' => http_build_query($urlparams)))); 我们有多个复选框和使用的命名约定 where : foreach ($checkboxes as $chbox )

// used variable variables to generate the data grid table based on selected fields
$'_field'.$chbox = (isset($this->params['url']['displayfields'][$chbox])?$this->params['url']['displayfields'][$chbox]:1);

$options = array('label'=>$chbox,'type'=>'checkbox','value'=> $'_field'.$chbox);
if ( $'_field'.$chbox ) $options['checked'] = 'checked';

echo $form->input('Filter.displayfields['.$chbox.']',$options);

在 post 方法中,复选框的命名约定是 Filter.displayfields.checkbox name 这有助于在 $this->data 或 $this->params['url'] 中获取数组 应该有一个用于 cakePHP 的持久分页插件/组件,这将使使用 cakePHP 开发生活变得更加轻松和有趣。 谢谢大家。

【讨论】:

以上是关于cakePHP 使用 post 数据分页,无需会话、序列化或 post 来获取的主要内容,如果未能解决你的问题,请参考以下文章

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

CakePHP - 加入表格后对数据进行分页

使用 CakePHP 分页助手的引导分页

在 CakePHP 中使用 saveAll() 保存多个 hasMany 数据,而无需在视图中写入 id

CakePHP多个会话

具有两个模型会话的 Cakephp 身份验证组件