ItGo.me Focus on IT Recommend

Home > CakePHP: best way to call an action of another controller with array as parameter?

CakePHP: best way to call an action of another controller with array as parameter?

2020腾讯云双十一活动,全年最低!!!(领取3500元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1074

【阿里云】双十一活动,全年抄底价,限时3天!(老用户也有),
入口地址https://www.aliyun.com/1111/home

In a controller, what is the most appropriate way to call the action of another controller and also pass an array as parameter?

I know that you can use requestAction to call actions within other controllers. But is it possible to pass arrays as parameters using request action?

And no, I do not want to put the action in the App Controller. So that is not a solution for me.

The only other way I know is to load the other controller as explained in: http://book.cakephp.org/1.3/en/The-Manual/Developing-with-CakePHP/Configuration.html#importing-controllers-models-components-behaviors-views-and-helpers

But is there an easier way to just call the other controllers action while passing an array as parameter?

I am new to cakePHP so any suggestion is appreciated. Thanks.

arrays cakephp parameters
|
  this question
edited Mar 3 '14 at 7:24 community wiki
2 revs, 2 users 96%
Vicer      Which cakephp version? could you add it? –  Philippe Gachoud Sep 29 '15 at 10:41

 | 

5 Answers
5

---Accepted---Accepted---Accepted---

Would it be appropriate for you to move the logic from the second controller into its model, then do something like this in your first controller's action?

$var = ClassRegistry::init('SecondModel')->myMethod($array);
$this->set(compact('var'));

Then, in the view for the first controller's action, you can use that data.

I always try to keep controller methods to actions you can hit through the browser, put as much logic in my models, call foreign model methods from controllers actions that need data from models that aren't the model for that controller, then use that data in my views, and if it's data that is viewed frequently, I create an element for it.


|
  this answer
edited Feb 28 '13 at 1:11 community wiki
2 revs, 2 users 88%
neilcrookes      good suggestion. I have heard somethings about separating logic from controller to model before. but still not clear about that concept. maybe as I gain more experience with cake, I will get a clearer picture. Thanks for your help. –  Vicer Oct 7 '09 at 4:25 4   Neil has the right idea. Controllers are intended to handle and delegate incoming requests. Business logic, or code that does stuff should primarily be in your models. –  Mark Story Oct 22 '09 at 5:33 1   I don't believe this is correct, models are for database access rules, the controllers handle everything else, the bulk of an application would be in the controller, in most cases.. I don't know what you mean by "code that does stuff".. anyways, the best practice IMO is to make code re-use a priority, so ideally a lot of stuff should be placed in controller componenets, the model is only used for stuff like data validation, etc, and in these cases should usually also be made into components (within the model folder) for re-use of these as well –  Rick Aug 16 '10 at 23:15 13   I disagree. Models should be fat, controllers skinny. As much logic should be put in models as possible. All your controller should do is process the request, deal with sessions, call model methods, set data for the view and handle userflow etc. If you find you are doing these things the same in lots of controllers, then create a component for it. BTW, did you know the comment you commented on, was written by the one of the lead developers of CakePHP? –  neilcrookes Aug 17 '10 at 22:39 1   The "fat models" mantra is not a justification for throwing anything and everything in them. Models are concerned with data retrieval and storage, and any methods that make those jobs easier belong in the model... but that's it. Business logic should technically not even be coupled to the CakePHP framework at all in either the controller or the model. It should exist in your own PHP "library" classes that the controller pulls into scope and uses as necessary, but this is a far more advanced approach than you typically see in Cake apps. –  beporter May 28 '14 at 15:01  |  show more comments

I would not advice to use the method requestAction but rather import, and instantiate the needed controller.

CakePHP doc says about requestAction that:

"It is rarely appropriate to use in a controller or model"

http://book.cakephp.org/view/434/requestAction

Once you imported and loaded the controller you can call any method of this controller with its parameters.

<?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);
    }
  }
?>

|
  this answer
edited Mar 3 '14 at 7:27 community wiki
2 revs, 2 users 98%
Schaoulli      thanks for your reply. yes I have heard that rumor about requestAction. wonder why it's not encouraged. Anyway, 'Import' is an alternate solution, thanks. –  Vicer Oct 7 '09 at 4:21      I agree, this is best, I had been using requestaction but it quickly shows why its not good, if you need to pass in a string that contains anything but basic text it won't work right, since its using the url method so it can't have special characters and if you use "/" in a string htis will break it into separate variables –  Rick Aug 16 '10 at 23:14      Using one controller action in another is quite common in a large app. Is there any news on if Cake will implement a standard single command to do so other than requestAction that even the documentation states has poor performance. –  Ryan Sep 26 '11 at 10:08      sorry for being that old the post to ask, but after loading the model and using it, is it necessary to unload it? –  hephestos Jul 18 '12 at 19:49 2   The variables defined need to go in a method, or perhaps this class constructor. But apart from that, I consider this a much cleaner solution than the other answer. Thanks! –  Josh Feb 7 '14 at 18:03  |  show more comments

As of CakePHP 1.2.5, you should be able to pass various parameter types through the second parameter in requestAction(). e.g.:

$this->requestAction('/users/view', array('pass' => array('123')));

Then in the UsersController:

function view($id) {
    echo $id; // should echo 123 I believe, otherwise try $this->params['pass'].
}

Instead of using 'pass' above, you can alternatively try 'form' and 'named' to pass form/named parameters respectively.


|
  this answer
answered Oct 2 '09 at 3:21 community wiki
Matt Huggins      Great! wasn't sure whether I can do that. Will try it. Thank you. –  Vicer Oct 7 '09 at 4:22      i can confirm that this works –  Mikelangelo Sep 29 '10 at 10:19

 | 

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);
    }
}

|
  this answer
answered Jan 8 '16 at 13:35 community wiki
Jocari

 |  -1

I put into my AppController class the following method and variable so it is caches in case of multiple calls

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;
}

|
  this answer
answered Sep 29 '15 at 10:54 community wiki
Philippe Gachoud      It's impossible that you have tested this code. It does throw syntax errors.. Eval..:? Sure? –  xcy7e 웃 Jan 12 '16 at 8:35

 | 

Recommend:yii - call action of another controller

at now i have this in controller 1 array( 'name'=>'title', 'value'=>array($this,'Action2'), ), and i get this error: controller1 and its behaviors do not have a method or closure named "Action2". if i replace $this

------splitte line----------------------------