Usually you do not have to care about the instantiation of controllers, it is done automatically for you by CakePHP. Though, in some cases it might be necessary to do it manually, at least I saw some people who tried it and failed. So, how do you do it?
The obvious way is to use the following approach:
$myController = new ExampleController(); $myController->test();
If you are “lucky” and you do not use components or models in the called method, then the snippet above works fine. In the other case, you will get a “Call to a member function on a non-object” error.
The reason for this error is that the models and components used by the controller are not constructed when you create a new instance of the controller. For this purpose you have to call the constructClasses() method before you use any controller methods. We can now rewrite the example from above to:
$myController = new ExampleController(); $myController->constructClasses(); $myController->test();
This probably works in most cases. I say “probably”, because if the used components use callback methods like initialize() or startUp(), then you have to call those callbacks yourself. The same is true if you want to use the beforeFilter() and afterFilter() callbacks in your controller.
Here an example with calling the initialize() callback method of the components (“Component” is misnamed, it is in fact a container which contains all components a controller uses):
$myController = new ExampleController(); $myController->constructClasses(); $myController->Component->initialize($myController); $myController->test();
This is a bit ugly, because you have to know implementation details of the controller you shouldn’t have to know…
Anyway, if you are interested in the complete instantiation and initialization process of a controller, have a look at Dispatcher::dispatch() and Dispatcher::_invoke().
This leads us to an alternative to the instantiation of a controller: to use a controller method indirectly by using Dispatcher::dispatch(). The example would then look like:
$dispatcher = new Dispatcher(); $dispatcher->dispatch('/example/test');
It depends on your specific use case whether this is a possible alternative, as with this approach you no longer have direct access to the respective controller.
Anyway, happy baking!