【发布时间】:2014-05-07 00:32:19
【问题描述】:
我希望通过控制器方法将用户发送到另一个页面。另一个页面需要 POST 数据。
通常,使用 postLink() 访问页面。有没有办法在控制器中使用它,也许使用 redirect()?
【问题讨论】:
-
用第一个控制器渲染第二页的视图怎么样?用户不关心 url,他们只关心浏览器中显示的内容。
标签: php cakephp redirect post cakephp-2.4
我希望通过控制器方法将用户发送到另一个页面。另一个页面需要 POST 数据。
通常,使用 postLink() 访问页面。有没有办法在控制器中使用它,也许使用 redirect()?
【问题讨论】:
标签: php cakephp redirect post cakephp-2.4
有点旧,但仍然没有接受答案,所以......
答案是否定的,是的。
不,没有直接的方法,因为您无法使用 redirect() 函数传递 POST 数据。
您可以使用 requestAction(),因为您可以传递已发布的数据 (see requestAction() here for version cakePHP>=2.0)。
在这种情况下,您传递一个 url,然后传递一个包含已发布数据的关键数据的数组,例如 $this->requestAction($url, array('data' =>$this->data));
或者如果您更喜欢$this->requestAction($url, array('data' =>$this->request->data)); requestAction() 的问题在于结果是环境问题,就好像您在当前控制器而不是目标中生成所请求操作的页面一样,导致效果不太令人满意(至少对于我来说通常不是组件表现不非常好),所以仍然没有。
...但是是的,您可以使用Session 组件执行非常类似的操作。
这就是我通常的做法。流程是这样的:
查看 A=>通过postLink() 到 A 控制器中的操作=>
=>A 控制器 request->data 到会话变量=>
=>通过 redirect() 到 B 控制器中的操作=>
=>从会话变量中设置 B 控制器 request->data=>
=>在 B 控制器操作中处理数据=>查看 B
因此,在您的 A 控制器中,假设在 sentToNewPage() 操作中您将拥有类似
//Action in A controller
public function sentToNewPage()
{
$this->Session->write('previousPageInfo', $this->request->data);
$url = array('plugin' => 'your_plugin', 'controller'=>'B',
'action'=>'processFromPreviousPage');
$this->redirect($url);
}
在 B 控制器中:
//Action in B controller
public function beforeFilter()
{//not completelly necessary but handy. You can recover directly the data
//from session in the action
if($this->Session->check('previousPageInfo'))
{$this->data = $this->Session->read('previousPageInfo')};
parent::beforeFilter();
}
public function processFromPreviousPage()
{
//do what ever you want to do. Data will be in $this->data or
// if you like it better in $this->request->data
$this->processUserData($this->request->data);
//...
}
【讨论】:
最好的解决方案是使用 javascript 来重定向。
但如果你想要更多蛋糕,我会给你一些工具 CakeAPI: requestAction - 它允许执行带有参数的控制器方法,如果您传递 'return',它将返回该操作的完整视图输出。
//very useful in views
$result = $this->requestAction('Controller/method',
array('return','user_id'=>$userId)
);
参数可以通过请求参数在控制器中访问
$this->request->params['user_id']
【讨论】:
总而言之,用POST数据模拟HTML表单并不容易和重定向,您需要设置一堆包含数据的隐藏变量并自动将表单发布到通过 Javascript 访问您的目的地。
我要做的是将处理功能从需要 POST 变量的函数中取出,并将其设为通用,以便您可以从两个函数中调用它。
考虑这个粗略的例子:
public function myPostDataAction() {
$name = $_POST['name'];
$age = $_POST['age'];
// do stuff
echo $name . ', ' . $age;
}
假设这是您在此场景中尝试向其发布数据的操作,但您不能这样做,因为如果没有此处顶部提到的场景,您无法通过重定向模拟那些 $_POST 变量。你可以这样做:
public function myPostDataAction() {
$name = $_POST['name'];
$age = $_POST['age'];
// call common function
echo $this->getMyResults($name, $age);
}
// accessible from inside the controller only
private function getMyResults($name, $age) {
return $name . ', ' . $age;
}
现在您还可以通过将常规旧变量传递给它来使用 getMyResults() 功能:
public function myProblemFunction() {
$name = 'John';
$age = 15;
echo $this->getMyResults($name, $age);
}
现在,显然您不会直接从控制器操作中输出类似的内容,而是将其设置为视图等,但这是您如何集中功能以在多个位置使用的示例。
对于免责声明,这种事情正是 models 的用途,您绝对应该考虑将这种功能放入模型而不是控制器中 - 这取决于您的特定应用程序。
【讨论】:
在 cakephp 2.x 中使用这个:
$this->autoRender = false;
$request = new CakeRequest(Router::url(array('controller' => 'mycontroller','action' => 'my_action')));
$request->data('dataIndex','value');
$response = new CakeResponse();
$d = new Dispatcher();
$d->dispatch(
$request,
$response
);
但它不会重定向而是分派到不同的控制器/动作,所以如果你继续 /controller/oldaction 它将保持当前 url(不进行 HTTP 重定向)。
您仍然可以使用 javascript 更改网址 见:Change the URL in the browser without loading the new page using JavaScript
【讨论】: