Controllers: Programming Application Logic | WebReference

Controllers: Programming Application Logic


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:

  1. How to interact with model classes from controllers
  2. How to pass controller data to the view
  3. How to create a controller action and use action parameters
  4. How to get form data from view
  5. How to redirect to another action
  6. How to add common functionalities to all controllers
  7. 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 ($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

  1. Put a fresh copy of CakePHP inside your web root folder. Rename the folder to applogic.
  2. Inside the /app/controllers/ directory, create a new PHP file books_controller.php and write the following code inside it.
  3. Inside the /app/views/ directory, create a new folder books. Create a new view file named index.ctp there (/app/views/books/index.ctp), with the following code:
  4. Now, visit the following URL and see what shows up in the browser: http://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 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:

  1. 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).
  2. 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.