CakePHP:以数组为参数调用另一个控制器动作的最佳方法?
Posted
技术标签:
【中文标题】CakePHP:以数组为参数调用另一个控制器动作的最佳方法?【英文标题】:CakePHP: best way to call an action of another controller with array as parameter? 【发布时间】:2010-12-03 05:08:43 【问题描述】:在一个控制器中,调用另一个控制器的动作并同时传递一个数组作为参数的最合适的方式是什么?
我知道您可以使用 requestAction 在其他控制器中调用操作。但是是否可以使用请求操作将数组作为参数传递?
不,我不想将操作放在 App Controller 中。所以这对我来说不是解决方案。
我知道的唯一其他方法是加载另一个控制器,如下所述: http://book.cakephp.org/1.3/en/The-Manual/Developing-with-CakePHP/Configuration.html#importing-controllers-models-components-behaviors-views-and-helpers
但是有没有更简单的方法来调用其他控制器的动作,同时传递一个数组作为参数?
我是 cakePHP 的新手,因此欢迎提出任何建议。谢谢。
【问题讨论】:
哪个 cakephp 版本?可以加吗? 【参考方案1】:CakePHP 2.X:
<?php
App::uses('AppController', 'Controller');
App::uses('PostsController', 'Controller');
class CommentsController extends AppController
public function index($parameter = null)
//Instantiate
$Posts = new PostsController();
//Load model, components...
$Posts->constructClasses();
//Call a method of Posts passing a parameter
$Posts->aMethod($parameter);
【讨论】:
【参考方案2】:我将以下方法和变量放入我的 AppController 类中,以便在多次调用的情况下进行缓存
var $controllersArray = array();
function _getController( $pControllerName )
if ( ! isset($this->controllersArray[$pControllerName]) )
$importRes = App::import('Controller', $pControllerName);// The same as require('controllers/users_controller.php');
$strToEval = "\$controller = new ".$pControllerName."Controller;";
$evalRes = eval($strToEval);
if ( $evalRes === false )
throw new AppException("Error during eval of given getController '$pControllerName'");
$controller->constructClasses();// If we want the model associations, components, etc to be loaded
$this->controllersArray[$pControllerName] = $controller;
$result = $this->controllersArray[$pControllerName];
return $result;
【讨论】:
你不可能测试过这段代码。它确实会引发语法错误.. Eval..:?确定?【参考方案3】:我不建议使用 requestAction 方法,而是导入并实例化所需的控制器。
CakePHP 文档说 requestAction 是这样的:
"很少适合用在 控制器或模型”
http://book.cakephp.org/view/434/requestAction
一旦你导入并加载了控制器,你就可以使用它的参数调用这个控制器的任何方法。
<?php
//Import controller
App::import('Controller', 'Posts');
class CommentsController extends AppController
//Instantiation
$Posts = new PostsController;
//Load model, components...
$Posts->constructClasses();
function index($passArray = array(1,2,3))
//Call a method from PostsController with parameter
$Posts->doSomething($passArray);
?>
【讨论】:
感谢您的回复。是的,我听说过有关 requestAction 的谣言。想知道为什么不鼓励它。无论如何,“导入”是另一种解决方案,谢谢。 我同意,这是最好的,我一直在使用 requestaction 但它很快就说明了为什么它不好,如果你需要传入一个包含除基本文本之外的任何内容的字符串,它就无法正常工作,因为它使用 url 方法,所以它不能有特殊字符,如果你在字符串中使用“/”,htis 会将它分成单独的变量 在另一个控制器中使用一个控制器动作在大型应用程序中很常见。除了 requestAction 之外,Cake 是否会执行标准的单个命令来执行此操作,是否有任何消息表明即使文档状态也表现不佳。 不好意思发了这么久的帖子,但是加载模型使用之后,是不是需要卸载呢? 定义的变量需要放在一个方法中,或者这个类的构造函数中。但除此之外,我认为这是一个比其他答案更清洁的解决方案。谢谢!【参考方案4】:将逻辑从第二个控制器移到它的模型中是否合适,然后在第一个控制器的操作中执行类似的操作?
$var = ClassRegistry::init('SecondModel')->myMethod($array);
$this->set(compact('var'));
然后,在第一个控制器操作的视图中,您可以使用该数据。
我总是尝试将控制器方法保留在您可以通过浏览器点击的操作中,在我的模型中放置尽可能多的逻辑,从控制器调用外部模型方法,这些操作需要来自不是该控制器模型的模型的数据,然后在我的视图中使用该数据,如果是经常查看的数据,我会为其创建一个元素。
【讨论】:
好建议。我之前听说过一些关于将逻辑从控制器分离到模型的事情。但仍然不清楚这个概念。也许随着我对蛋糕的了解越来越多,我会得到一个更清晰的画面。感谢您的帮助。 尼尔的想法是正确的。控制器旨在处理和委托传入的请求。业务逻辑或做事的代码应该主要在你的模型中。 我不相信这是正确的,模型用于数据库访问规则,控制器处理其他所有事情,大部分应用程序将在控制器中,在大多数情况下......我不知道你所说的“做事的代码”是什么意思。无论如何,IMO 的最佳实践是让代码重用成为优先事项,所以理想情况下,很多东西应该放在控制器组件中,该模型仅用于类似的东西数据验证等,在这些情况下,通常也应制作成组件(在模型文件夹中)以供重复使用 我不同意。模型应该很胖,控制器应该很瘦。尽可能多的逻辑应该放在模型中。你的控制器应该做的就是处理请求、处理会话、调用模型方法、为视图设置数据和处理用户流等。如果你发现你在很多控制器中做这些事情都是一样的,那么为它创建一个组件。顺便说一句,您知道您评论的评论是由 CakePHP 的主要开发人员之一编写的吗? “胖模特”的口头禅并不是向他们扔任何东西的理由。模型涉及数据检索和存储,以及任何使这些工作更容易的方法属于模型...仅此而已。从技术上讲,业务逻辑甚至不应该在控制器或模型中与 CakePHP 框架耦合。它应该存在于您自己的 PHP“库”类中,控制器将其拉入范围并根据需要使用,但这是一种比您通常在 Cake 应用程序中看到的更高级的方法。【参考方案5】:从 CakePHP 1.2.5 开始,您应该能够通过 requestAction() 中的第二个参数传递各种参数类型。例如:
$this->requestAction('/users/view', array('pass' => array('123')));
然后在 UsersController 中:
function view($id)
echo $id; // should echo 123 I believe, otherwise try $this->params['pass'].
除了使用上面的“pass”之外,您还可以尝试使用“form”和“named”分别传递表单/命名参数。
【讨论】:
太棒了!我不确定我是否可以这样做。会试试的。谢谢。以上是关于CakePHP:以数组为参数调用另一个控制器动作的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章
如果给定的操作不存在,则定义 Cakephp 路由以调用特定的控制器