15 Essential CakePHP Tips

Note, this article was written a long time ago for CakePHP version 1.x … many of the points described here still apply in the latest 2.x versions of CakePHP.

1. Save() does not work!
Sometimes it happens that save() fails without any obvious reason. Your data array looks fine and you’ve build the form correctly, etc., etc., but no query was executed. It is very possible that save had failed due to validation errors. Maybe you are updating some model and while the current fields in the form pass the validation, there is a chance that some “other ones” are causing the validation rules to fail. An easy (and helpful) way to see what’s going on with validation is to do pr($this->validationErrors); in your view. By employing this method you’ll see exactly what’s happening with your model’s validation. The other option is to pass false as a second parameter to save(); in order to disable the validation. However, the latter method does not give much of hint and should not be used to fix a failing problem, but rather to purposely avoid validation.

2. Save() still does not work!
Do you have beforeSave(); in your model or app model? Always double-check for this method, and even more importantly, ensure that it returns true.

3. Validating on create or update
CakePHP has an ‘on’ key to be used in your $validate array. It allows you to specify whether the rule should be enforced during a new record creation or during an update of an existing record. For example, if you only want to check for a unique email address when you are creating a new User account, you’d add ‘on’ => ‘create’ to your $validate array. Therefore, this rule will be ignored when you are updating/editing some user.

4. Mind your cache
You’ve made some changes to your tables, but your app “ignores” them… You’ve moved some things around, bur your app doesn’t seem to “notice” that…
Clear the cache. Delete the files from your app/tmp/cache. Be sure to only delete the files and not the directory structure.
Basically if you notice some strange behavior in your app, just keep in mind that it could be caused by the cache.

5. I’m losing the extra URL parameters when paginating
You need to retain some extra URL parameters during pagination. For example the URL is something like /products/view/45. Yet, when you build the pagination the ID (45) is lost… Well, all you need to do is add this line of code to your view: $paginator->options(array(‘url’ => $this->passedArgs));

Update: this is likely fixed in the recent builds of CakePHP, but still good to be aware of.

6. Using afterFind()
Model::afterFind() allows you to perform some data manipulation after the Model’s find method. Here’s a sample usage in the model:

function afterFind($results, $primary=false) {
  if($primary == true) {
  // do stuff to the $results

  return $results;

$primary will be set to true after your find() method is executed and some results are returned. After you modify the $results you will return them back to your app (controller).

7. I need to know the basic information about my table
Try this: pr($this->ModelName->schema())

(Thanks, gwoo, for the hint)

8. How do I check for a non-empty field in CakePHP 1.2?
Update: cake core now has a ‘notEmpty’ rule built-in, so definitely use it instead.

For historic purposes only:
The old VALID_NOT_EMPTY constant is now deprecated and there does not seem to be a rule to replace it… Well, it’s easy enough by using: ‘rule’ => array(‘minLength’, ‘1’)

Martin Bavio pointed out that having space characters (only) as your field data will make the validation rule pass and this is probably not a desirable effect. Using this simple regex, instead, will catch an empty string with space characters: ‘rule’ => array(‘custom’, ‘/\S+/’)

9. Avoid using the $uses array
You’ve got two completely unrelated models, but you need info from one in the controller of another. The first idea is to add them to the $uses array. Hey, it’s easy and gets the job done. Well, to make the long story short, it’s bad practice. Think about your model bindings and ensure that models are really not related to one another. Sometimes your User model is definitely not related to CommentRating, but you absolutely need it in your users controller. Well, just by chance it appears that User->Post->Comment->CommentRating. It’s a deep binding that may not be obvious at first, but by employing such a chain of models you can easily avoid using the $uses array, when it’s really not necessary.

Update: if you truly need to load some random (and definitely unrelated) model in your controller, do it like so in the given action:

As soon as this line executed you’ll have an instance of MyModel available in $this->MyModel (pr($this->MyModel); to see your freshly loaded object.

Another option is to use this approach:
$MyModel = ClassRegistry::init(‘MyModel’);

Which is nice, because it allows you to do things like this:

$someData = ClassRegistry::init(‘MyModel’)->find(‘all’, array(‘conditions’ => array(‘MyModel.name LIKE’ => ‘% ‘. $name . ‘%’ ))); (the latter, chaining, example is PHP5 only)

10. Clean-up ugly HTML

It’s no secret that CakePHP often outputs some very ugly and hard to read HTML. This little trick will make it a lot cleaner.
Create a file named app_helper.php in your app’s root directory.

Next add this function to it:

function output($string) {
return parent::output($string . “\n”);

Take a look at your HTML now… much better.

(Thanks, TommyO, for the hint)

11. How can I access session data in the view?
Very easy. You have the $session helper available.
Just try it: pr($session)
Update: if you have already written some variables to the session, then try pr($session->read());

12. I need to save data from multiple models
Don’t even think about using loops and other trickery. There is a very nice (but not well documented) method saveAll() available. It will let you save data from multiple models at once. Granted, it takes a little time to figure it out, but once you get it working it is really a time saver. Try using it with some dummy data, and make sure that your data array is properly formatted and associations are setup correctly.

13. Static pages and routes
I really don’t like having /pages/ as part of the URL for my static pages. Well, they are static… so let’s make them .html instead (at the same time we sprinkle just a little of security by obscurity mantra).
If you had links pointing to www.example.com/pages/myPage/ they should now point to www.example.com/myPage.html and add this to your routes:

Router::connect(‘/(.*).html’, array(‘controller’ => ‘pages’, ‘action’ => ‘display’));


14. The fastest way to build a form in CakePHP

echo $form->create();
echo $form->inputs();
echo $form->end();

It is just a step beyond scaffolding, but really this is how easy it is to build a form in CakePHP. Just give it a go.

15. Get to know CakePHP by using Github

CakePHP is constantly evolving and if you are serious about developing on top of this framework it is very important to keep up with the latest and greatest and to get familiar with some of the new and upcoming features. https://github.com/cakephp is a great place for this.

Related Posts