Last time we created a database table, and baked a basic view and layout for our Events database. This time round, we're going to take a step back from development and look a little bit into what makes CakePHP tick, we'll also look at some of the big changes between CakePHP 2.x and CakePHP 3.
At it's core, CakePHP is a PHP based framework that is written using the Model-View-Controller (MVC) architectural pattern. I won't bore you with a history of MVC, but if you're interested then have a read at http://c2.com/cgi/wiki?ModelViewControllerHistory and http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html. Essentially, MVC breaks your application into three distinct, but inter-connected layers. Each layer handles a certain part of your application and encourages the separation of concerns design principle. The layers make up the MVC name, namely Model, View and Controller.
The model layer is the brain of your application. This is where most of your business logic should be situated. The primary purpose of the model layer is handling your data. It is responsible for retrieving or saving data from your data storage solution (Database, File system, etc.), it also handles data validation and data processing. Basically anything to do with reading, writing or modifying data should be here.
The model layer is the part of CakePHP that has seen the biggest change in version 3. In previous versions, the model layer consisted of Model classes, and Behavior classes. The Model classes represented your data source and the data stored within (in an array format). Each Model would represent a single database table (for example) and would make use of a DataSource to read and write data to the database table. Models also dealt with validation data using a Validator class. Behavior classes added common functionality to one or more Models, for example, automatically capturing the user who modified a record, or maintaining a tree structure.
In CakePHP 3, the model layer has changed completely. There are now Table classes, Entity classes, Behavior classes, and a Query class. Table classes represent your data store (Usually a database table) and are responsible for fetching, saving and validating your data. Tables are also responsible for manipulating bulk data (e.g. calculating totals out of a collection of data). They are very close to being synonymous to the Models of old. Entity classes are an entirely new concept and they represent single data points (i.e. a row in a database table). Using Entity classes allows you to create some very complex virtual data fields. Behavior classes work exactly the same as previously. The new Query class gives CakePHP 3 an incredibly powerful way of interacting with standard relational databases (i.e. SQL) through what is called a fluent interface. Fluent interfaces give a very simple, fluent interface for interacting with objects. A simple example of the new Query class.
/** * Assume that $connection and $table have already been set earlier * $connection is the database connection (A Cake\Database\Connection object) * $table is the table object to run the query on (A Cake\ORM\Table object) */ $query = new Cake\ORM\Query($connection, $table); $query ->select([ 'id', 'first_name', 'last_name', 'email_address' ]) ->where([ 'status' => true, 'email_address LIKE' => '%@gmail.com' ]) ->order(['last_name' => 'ASC']);
The above query will generate the following SQL.
SELECT id, first_name, last_name, email_address FROM users WHERE status = 1 AND email_address LIKE '%@gmail.com' ORDER BY last_name ASC
For more complex examples, take a look at the CakePHP book
If the Model layer is the brains, then the View layer is the skin of your application. This layer represents what the end user will see and contains your HTML, JSON or XML templates, Helper classes, View classes, and View Cells. If you are coming from CakePHP 2, then the View layer is pretty much the same. Big changes, include the splitting of Templates (ctp files), and the View layer classes into two different directories, and the addition of View Cells.
Helper classes allow you to group commonly used output functionality into logical classes, for example, the built in FormHelper which generates form fields. View classes encapsulate functionality required to render the output, CakePHP comes with a JsonView class which provides a quick and easy way to output JSON formatted data. There is also the FriendsOfCake CakePDF plugin which makes use of one of the many HTML-to-PDF converter tools to render a PDF file. Finally, View Cells provide a simple interface for creating self-contained content cells that need, as an example, to read data from the database. View Cells would be used in a dashboard, or a messages panel.
The Controller layer would be the heart of your application. This is the layer that has had the fewest changes between CakePHP 2 and CakePHP 3. It is responsible for controlling the flow of data throughout your application and generally should have the least amount of code.
Incoming client requests are routed to a specific controller action which would have the logic required to determine what data is required and what table it can be found in, if the requester is allowed to access the data and what View must be used to output the data. The Controller layer consists of Controller classes and Component classes. Component classes are similar to Behaviors from the Model layer and Helper classes from the View Layer. They encapsulate common functionality that is to be shared amongst your Controller classes (An example is authentication).
A CakePHP request
The CakePHP Book has a very pretty picture showing how a CakePHP request. A typical CakePHP request works as follows.
- The CakePHP dispatcher uses the Router to determine which controller action should be invoked in order to serve the incoming request
- The controller would then check for authentication details (if necessary) and any request parameters such as IDs, file extensions, etc.
- The controller action requests the required data from the model layer
- The model layer fetches the requested data from the data store and manipulates and formats it as required and returns the data to the controller
- The controller then passes the data onto the view layer
- The view layer renders the data into HTML (Or JSON, XML, etc.)
- Finally the controller returns the output of the view layer to the dispatcher which sends it to the client.