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
Most commonly, one single controller manages the logic for one single model. In chapter 3, we already saw how CakePHP automatically finds out that relevant model's class name from a controller's name. The related model class is automatically associated and can be accessed from the controller—we don't need to configure it in the controller class explicitly. In the previous chapter, we also saw an example of this automatic binding. We created a
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 (
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 file
books_controller.phpand write the following code inside it.
- Inside the
/app/views/directory, create a new folder
books. Create a new view file named
/app/views/books/index.ctp), with the following code:
- Now, visit the following URL and see what shows up in the browser:
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 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
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.
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
http://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
BooksControllerwill 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.