What we Learned about CakePHP
Posted on April 30th, 2007 under Client Work, Code, PHP.
We launched Tech Dispenser for Computerworld last week. It is based on bleeding-edge CakePHP - version 1.2.xxx. Coming off of a few Ruby Rails (RoR) projects, we found things we liked about Cake, and some things we didn’t. Here is a review with some of our recommendations you might be interested in when you start your next Cake-based project. This article would be especially useful for Rails developers working on a CakePHP project for the first time.
CakePHP has no Database Migrations
We believe that everything ought to be checked into subversion (our version control system). This includes any core libraries (like Cake itself), test suites and even development scripts and utilities. This is all in effort to be able to build a “one-button” development environment from SVN. So a very important part of this is the database schema and iterations.
Because migrations weren’t available, we quickly rolled our own external command-line routine written in PHP (attached to this message, it is for MySQL only). We place it in the ./scripts directory. Each migration is a pair of files (i.e. an UP and DOWN), and should reside in a directory called /config/sql/migrations.
$ ./scripts/migrate.php [version, optional]
This will move the current database to the migration version (or the most recent if none passed). Also attached is a rebuild_db.php, which rolls back the migration to “0″ and then to the most recent version (along with running any fixtures).
$ ./scripts/rebuild_db.php
For most applications, the database is an integral part of the model (following the MVC pattern). So agility with all aspects of the model is mandatory, meaning database migrations are also mandatory
The good news is since we started, there appears to be a few options people have contributed in the way of database migrations (this one looks promising). The bottom line/recommendation we have it make sure you install/build/create a process for database migrations in your next CakePHP project.
There is no Embedded Webserver
Those coming from RoR will also notice there there is no embedded webserver, like Webrick. So you have to manually setup your favorite web browser. Non-RoR people probably wouldn’t even notice this, but the drive to a “one-button development environment” calls for an embedded development web server. We can use SQLite to have a zero-config database management system, so the only thing really missing is the web server.
I found a project called Nanoweb, but we didn’t implement it. Rather, each developer was responsible for setting up and configuring Apache manually. The team was small and well versed in Apache configuration, so it was fairly smooth. I would recommend to either explore Nanoweb (and check the web server right into your project SVN) or make sure to commit any httpd configuration information (or setup scripts).
Test Driven Design
It seems that CakePHP does not have the facilities “out-of-the-box” to enable TDD (Test Driven Design). We believe that tests ought to drive the development, extending directly from the specification.
If you value TDD as much as we do, you should look into installing SimpleTest. Then follow this article on Unit Testing for CakePHP.
Cake’s ORM - Object Relationship Model
The ORM is for the most part adequate in CakePHP. The one difference RoR folks will find is how relationships are bound. In Rails, you typically get what only what you ask for. So if a company model has many persons, the company object will only contain company metadata - until you ask for more information. I think this has to do with CakePHP supporting both PHP4 and PHP5 and the lack of the “magical” __get() (i.e. perl’s AUTOLOAD) method in PHP4. In Cake, a recursion level is defined (i.e. go “2″ levels deep). As this has overhead, an unbind model method is available to limit unnecessarily CPU cycles. So make sure you are only going as deep as necessary - it will cut down drastically on the number of SQL calls.
The other nuance we found with the ORM in Cake is the return types from the model. I would expect whenever running a static method (i.e. find_by_name), a collection (or list/array of objects) would come back. I imagine this may have to do again with the poor object model in PHP4, but the inconsistency can sometimes be tedious.
Error Handling
The inline errors in CakePHP really ought to be improved. Errors from the controllers and models die out to the screen, as typical for PHP. Adding in a backtrace (like Carp::confess in perl or the nice trace in RoR) would be a huge value add. As for template errors, they really ought to be captured and dealt with as the rest of the errors (instead of the unusable absolutely-positioned error block in the template).
For an enterprise application, creating a custom error handler for Cake is a must.
Documentation
As with almost any (new) project, the documentation for CakePHP is not to the level of RoR. In fact, at the time of this article, the CakePHP Wiki is off-line. I think in retrospect, some of our documentation woes had to do with our choosing of the bleeding edge Cake, but even the 1.1.xxx versions seem a bit under-documented. In hindsight, I would recommend staying with the last stable release to increase your access to documentation and finding articles and example code online.
Summary
All-in-all CakePHP was a good experience for us. It may not have the maturity of RoR, but it is an adequate framework when faced with a mandated PHP production environment.
