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 来获取的主要内容,如果未能解决你的问题,请参考以下文章