This past month, the CakePHP team announced the launch of the alpha release of CakePHP 3. The Cake development team considers version 3 to be a game changer, so with the alpha release of version 3 now hot out of the oven, this article takes a fresh look at CakePHP 3 as an effective modern framework for PHP development.

A Brief History

These days, there are so many options when it comes to PHP development. As PHP has matured, more and more PHP Frameworks have come onto the scene, providing developers with a wide array of choices. But it hasn’t always been that way.

Back in 2005, when PHP 4 was still the standard, there were no PHP frameworks and developing an object oriented coding approach in PHP was certainly a challenge. It was then that CakePHP emerged – the first-ever PHP MVC framework. In the nearly 10 years that have passed since it was first released, CakePHP has continued to evolve, maintaining a healthy market share of PHP developers.

Just how popular is the CakePHP framework? It is ranked in the top 4 most popular PHP projects on GitHub, of around 130,000 projects, with over 18,000 members in the CakePHP Google group with 32,000 topics. With 270 contributors to the code, and 320 contributors to the documentation, there is no denying that CakePHP has a big following. CakePHP’s current widespread and growing popularity is well summarized in an article by James Watts, core member and community manager of CakePHP for the Cake Software Foundation, who I interviewed in the course of writing this article.

With version 3 of the framework now available, CakePHP is most certainly expected to remain a leading force in the PHP world and a major contender amidst today’s varied landscape of PHP frameworks.

What’s new in version 3 of CakePHP?

This review is based on the alpha release of CakePHP 3.0, which incorporates a number of new features and enhancements including:

Better performance. Version 3 incorporates performance improvements to the bootstrap process, the routing process, and several parts of process for generating helper templates.

Enhanced components and helpers. Version 3 provides enhanced support for “flash messages” with its new FlashHelper and FlashComponent. In addition, the CookieComponent has been enhanced, making it easier to separate the configuration of cookie namespaces and the handling of cookie data.

Improved session management. Session management has always been a static class in CakePHP which has proven to be problematic in a number of ways. With version 3, you can now access the session from the request object $this->request->session() . This change also makes the session easier to test, and enables CakePHP to use PHPUnit 4.x.

Improved consistency of conventions. The application skeleton and plugin skeletons have been updated to use the same directory structure in order to be more consistent with one another.

Themes and plugins merged. A key goal of CakePHP 3 was to make themes more powerful and robust. Working toward that goal, it became apparent that what was really needed was for themes to provide the same capabilities as plugins. Accordingly, any plugin may now be used as a theme, which also simplifies packaging and redistribution.

ORM Improvements. Several API changes have been made to the ORM (Object-relational mapping). Most notably, it’s now simpler to specify deep associations for saving operations, and a couple of conventions have been changed to reduce the learning curve and confusion among new adopters.

In addition, there are a few additional features that are also planned to be incorporated into the beta release of version 3.0. Most importantly:

Internationalization and localization (i18n and L10n) feature enhancements

A replacement for CacheHelper based on Edge Side Includes

A new routing API for simpler and faster route declaration

Indeed, version 3 represents a significant upgrade beyond prior versions of CakePHP.

Why CakePHP?

While CakePHP has many great features, this review focuses on a few in particular that really help set it apart, namely:

Convention over configuration

CakePHP has always been about rapid and consistent development and, toward that end, CakePHP places a heavy emphasis on convention. Therefore, like Ruby on Rails (from which CakePHP drew much of its inspiration), CakePHP adheres heavily to the convention over configuration principle.

Conventions mean that a developer doesn’t have to think about “where things go” when learning how to use the CakePHP framework, since defaults for these rules are already put in place. While one does need to become familiar with the CakePHP conventions, once mastered, the developer can concentrate on core development, rather than needing to worry about where the code is placed and other configuration issues.

CakePHP’s conventions are in stark contrast to PHP itself, which is a fairly liberal language. As a result of its conventions, CakePHP helps to ensure more consistency in coding style and structure across multiple developers and even across multiple teams. By adopting a standard set of conventions, Cake strives to make development more consistent.

For a database schema, for example, CakePHP makes certain default assumptions in terms of how certain variables, table names, and fields will be named. Specifically, Cake expects that:

Table names will be plural (e.g., orders )

) The name of the primary key field will be id

The names of any foreign key fields will be based on the referenced table name followed by _id (e.g., the foreign key into a customers table would be named customer_id ).

To illustrate, let’s consider a simple review of two tables ( articles and users ) from a blog post database. In our example, we’ll say that an Articles “BelongsTo” a Users , and a Users “HasMany” Articles . These relationships would be specified as follows in CakePHP 3.0:

In ArticlesTable.php: class ArticlesTable extends Table { public function initialize(array $config) { $this->belongsTo('Users'); } } In UsersTable.php: class UsersTable extends Table { public function initialize(array $config) { $this->hasMany('Articles'); } }

CakePHP assumes the default conventions and thereby automatically knows what foreign keys to look for (i.e., user_id in the articles table) when fetching any associations.

It is important to emphasize, though, that CakePHP 3 does allow for its default conventions to easily be overridden. For example, let’s say our foreign key in the users table was called author_id instead of user_id . Specifying this would just require the following two small changes to our code to let CakePHP know that we’re not using the default:

In ArticlesTable.php: class ArticlesTable extends Table { public function initialize(array $config) { $this->belongsTo('Users' => ['foreignKey' => 'author_id']); } } In UsersTable.php: class UsersTable extends Table { public function initialize(array $config) { $this->hasMany('Articles' => ['foreignKey' => 'author_id']); } }

So, although conventions are indeed integral to CakePHP and definitely do have their advantages, overriding them when necessary is really quite simple, as we’ve shown here.

While some developers may prefer PHP frameworks (such as Yii and Laravel) that don’t rely as heavily on conventions, CakePHP conventions can in fact be quite advantageous. They can help dramatically reduce ramp-up time for a CakePHP developer when tasked with enhancing or maintaining code written by another developer, since they result in consistent coding structure and conventions across multiple CakePHP developers and projects.

CakePHP’s Object-relational mapping (ORM)

CakePHP’s Object-relational mapping (ORM) benefits greatly from CakePHP’s framework conventions. By setting out the database schema to Cake’s standards, you can quickly connect tables together through Cake’s powerful ORM. You’ll rarely need to write an SQL statement, as CakePHP handles things like table joins, hasMany , and even hasAndBelongsToMany relationships with ease.

Leveraging CakePHP’s ContainableBehavior , through your model associations you can specify which database tables and fields to select from an SQL query. This can go several tables deep, and through the ORM it is easy to rapidly construct highly complex SQL statements.

Incidentally, CakePHP’s ContainableBehavior is a great example of how CakePHP can simplify and streamline PHP development. It helps you search and filter data in a clean and consistent way and can also help increase the speed and overall performance of your application. (It works by temporarily or permanently altering the associations of your models, using the supplied containments to generate a corresponding series of bindModel and unbindModel calls.)

The challenge with the ORM is that it makes using SQL so simple that, if a developer isn’t careful, he or she can write inefficient SQL queries without meaning to. I have certainly seen poorly written Cake applications many times which haven’t streamlined their queries. These problems tend to surface a couple of years after a system has been deployed, when databases get bigger and badly written queries become increasingly slow.

The main issue here is that, prior to the latest CakePHP version 3, Cake’s ORM would by default retrieve any associated tables when performing a query. As a result, a simple “find all” query could potentially become quite bloated as the underlying SQL would retrieve all data from all associated tables. In version 3, this behavior is no longer the default. (And in prior versions of CakePHP, this default behavior is easy to disable by simply adding public $recursive = -1; to your main AppModel.php file.)

Overall, a review of Cake’s ORM shows it really does help streamline development and, if used correctly, is an amazing tool for building complex queries quickly. It is nonetheless vital that developers take the time to fully understand the ORM and to ensure that their queries are are properly optimized (as is true in any language).

Components and Helpers: CakePHP Libraries

One of the great features of CakePHP is the built-in libraries – Components and Helpers – that eliminate many boring, repetitive, and tedious development tasks. In the MVC context, Components help streamline controller development, while Helpers simplify view coding and logic (i.e., the presentation layer).

The PaginatorComponent , for example, auto-magically builds a next/previous page interface from a find query. Add the JsHelper , and suddenly you have AJAX Pagination, powered by your favorite JavaScript framework (jQuery by default).

A quick sampling of a other useful Helpers includes:

TimeHelper : Makes displaying dates and times a breeze, providing a suite of functions for formatting and evaluating time values.

: Makes displaying dates and times a breeze, providing a suite of functions for formatting and evaluating time values. NumberHelper : Provides convenient methods for displaying numbers in a variety of common (or customized) formats and precisions.

: Provides convenient methods for displaying numbers in a variety of common (or customized) formats and precisions. TextHelper : Aids in enabling links, formatting URLs, creating excerpts of text around chosen words or phrases, highlighting key words in blocks of text, and gracefully truncating long stretches of text.

And there are many more.

Criticisms of CakePHP 3

To be sure, every framework has its pros and cons, and CakePHP is no exception. Here are some of the most common criticisms leveled at CakePHP outside of this review:

“Legacy framework; bloated and slow.” This criticism is typically more of a historical one, with limited (if any) truth today. Supporting PHP versions as far back as PHP 4 has historically required CakePHP to deal with many of PHP’s own legacy issues. With the maturing of PHP, and with the release of CakePHP version 3 in particular, this allegation really has lost its validity.

“Overly strict and confining.” While there are clear advantages to the CakePHP conventions, there are those who criticize them nonetheless. Critics often argue that the conventions are too strict, but they fail to recognize (or acknowledge) that these conventions can be easily overridden. By adopting a standard set of conventions, Cake looks to make development consistent which, given PHP’s otherwise loose coding practices, should only be seen as a positive thing.

“Slow release cycle”. A slow release cycle is not necessarily bad. To the contrary, a release cycle that is too aggressive can actually be more problematic. In fact, part of the reason that CakePHP major releases take time is to ensure backward compatibility with earlier versions of PHP that are still widely deployed. Moreover, this conservative release cycle and emphasis on backward compatibility eliminates the need for major (and frequent) changes to your code when new versions are released. It should also be noted that the CakePHP 3 team is anything but slow when it comes to minor releases (bug fixes, patches, minor enhancements, etc.), which are released monthly. Similarly, most bug tickets are answered within hours of being posted.

“Not an out-of-the-box solution.” In contrast to many other modern “web app out of the box” PHP frameworks (such as Yii, for example), CakePHP purposefully looks to support and enable custom solutions. I have personally benefited from this greatly in developing a number of large, custom, database-driven web sites and applications.

“Uses data arrays rather than objects.” This is no longer true, as of version 3. In previous versions, any data would need to be stored and referenced as nested arrays (e.g., $user['User']['username'] ). CakePHP 3 finally addresses this, instead storing data as objects (e.g., $user->username ).

“Poor documentation.” There is some validity to this criticism, in that CakePHP documentation doesn’t always appear to have been written with the beginner in mind (important information is sometimes discussed in just a sentence or two, whereas a few paragraphs of discussion would probably have been warranted). The Cake development team is aware of this and is working to improve the documentation accordingly. In fact, the home page of the CakePHP 3 documentation explicitly states a high level of commitment to the “quality, validity and accuracy” of the documentation. As CakePHP is a community driven framework, an “Improve this Doc” button is provided on every page of the documentation, enabling and encouraging CakePHP users to contribute their own additions, deletions, or corrections to the documentation.

Conclusion

All-in-all, nearly 10 years after its initial release, a review of CakePHP reveals that it remains a vibrant and formidable competitor to the many other PHP frameworks that have since emerged.

CakePHP is a complete and comprehensive development solution. The code base is mature and the functionality seems endless. Overall, Cake has been built to make development rapid, which is important not only for software developers, but also for investors. The biggest cost of software development is the cost of the development time, and CakePHP aims to reduce development time significantly.

CakePHP is a community run project. It can only get better as more and more people get involved. Having been involved for 7 years and seen the community continue to grow, I am excited about this next stage for CakePHP. The launch of CakePHP 3, and the maturity of both PHP and CakePHP, means that the framework will continue to get better and better.

If you are looking for a PHP-based solution that offers many benefits similar to Ruby on Rails (in terms of ease-of-use and convention over configuration), then give CakePHP a whirl. The CakePHP Blog Tutorial only takes a few minutes to set up and run though, or alternatively, CakeCoded offers a series of clear lessons to help acquaint a PHP developer with CakePHP and to get started using it. With these resources, you will quickly see the extent to which CakePHP can speed up and enhance your PHP software development efforts. Enjoy!

Michael Houghton is a Toptal Engineer based in Ireland with extensive CakePHP experience. He has developed over 100 websites with the framework, worked with the team at CakeDC (the commercial entity behind the CakePHP framework), has submitted various patches, and has helped with the CakePHP documentation.