Controller, the name suggests its job—it controls, supervises, and manages. In CakePHP, controllers are the classes that handle browser requests and facilitate communication between models and views. It is the central hub where application logics are defined to control program flows of browser requests.
In CakePHP, every public method of a controller is called 'action'. Each action represents a URL. When a URL is requested from browser, the respective controller action is invoked. A controller generally uses a model class to manipulate and process the user data. Once the data is processed, controller takes it from the model and forwards it to the appropriate view file. The view file is then sent back as the response and displayed in the user's browser. In such a way, controller coordinates between the user, the model, and the views.
In this chapter, we will learn the nuts and bolts of CakePHP controller. We will particularly find out:
- How to interact with model classes from controllers
- How to pass controller data to the view
- How to create a controller action and use action parameters
- How to get form data from view
- How to redirect to another action
- How to add common functionalities to all controllers
- How to create reusable components that can be used to add functionalities to controllers
Interacting with Model
TasksController
class and CakePHP automatically found out and attached the related model Task
(through its naming convention) with the controller. We were able to access the Task
model from the TasksController
as if that model class is a controller attribute ($this->Task
).
Attaching Models and Controllers
In CakePHP, generally, every controller has one dependent model class. That's the way Cake is designed to be used. CakePHP will always look for a related model class for a controller through its naming convention unless a controller-model attachment is explicitly defined in that controller. Now, in some unusual situations, we may need a controller that does not have any dependency on any model class. In that case, we have to configure our controller to handle this scenario. Let's see how such a model-less controller can be created.
Time for Action: Controller without a Model
- Put a fresh copy of CakePHP inside your web root folder. Rename the folder to applogic.
- Inside the
/app/controllers/
directory, create a new PHP filebooks_controller.php
and write the following code inside it. - Inside the
/app/views/
directory, create a new folderbooks
. Create a new view file namedindex.ctp
there (/app/views/books/index.ctp
), with the following code: - Now, visit the following URL and see what shows up in the browser:
https://localhost/applogic/books/
What Just Happened?
At first, we have created a new CakePHP project. We already know how to create and configure a new Cake project from Chapter 2. In this case, as we don't need any database, we did not set up the database configuration file (/app/config/database.php
). Cake will not find any database configuration file but it will work.
We then created a controller class named BooksController
. Inside the controller, we defined an attribute named $uses
. The $uses
attribute is a special controller attribute that is used to explicitly define the relevant model class name of a controller. If $uses
is not defined, Cake tries to find out the relevant model name through its naming convention. We assigned an empty array to this $uses
attribute in BooksController
. It means that BooksController
does not use any model class. We could also assign $uses
to null
like the following, which would also do the same:
We then wrote an action named index()
inside the BooksController
. And, we also created the corresponding view file (app/books/index.ctp
) for this particular action.
The index()
action contains no code. And hence, when this action will be requested, Cake will just render its related view file.
When someone visits the URL https://localhost/applogic/books/
, the default action (that is index()
) of the BooksController
is invoked, and the related view file is rendered. It displays something like the following in the browser.
In CakePHP, we can associate models with controllers in 2 ways:
- Automatic binding: CakePHP automatically binds a model with a controller through its naming convention. Like a controller named
BooksController
will be tied with a model named Book automatically (unless something else is manually defined). - Manual binding: If we want to override the automatic binding, we can assign $uses controller attribute to an array of models. Those models will be available to the controller.
'Convention over configuration' is one of the principal philosophies of CakePHP framework. It is recommended to follow the naming conventions of controllers and models and let Cake attach related controllers and models automatically. It would simplify things.
We have already seen how the second method (Manual binding) works. We assigned an empty array to $uses
attribute of BooksController
to tell Cake that this controller has no dependency on any model class. We could also manually attach more than one model(s) to a controller using the $uses attribute. In that case, we just have to put all the model names in the $uses
attribute, like this:
We just learnt how controllers can be tied up with models. Now, we will see how they can interact with the presentation files, a.k.a views.