E_STRICT compliance in Cake

In PHP5.4 E_STRICT will be automatically be part of E_ALL. So it might be a good idea to get your code E_STRICT ready.
I have to say: I never bothered myself. Always used E_ALL & ~E_STRICT (the second part will now be necessary in 5.4 if you plan on skipping the E_STRICT part) and didn’t bother about those notices.

With my recent contribution to the 2.1 core pretty much all of my helpers, components, behaviors, models, … are now finally E_STRICT compliant. Which does not only make me happy, it also makes me think if I can drop my personal E_STRICT boycott now.

Most of those notices resulted out of incorrect method declarations. They have to be of the same type as the parent (some type, same number of params, …) which sometimes can get really annoying if you want to override a parent method.
Depending on the specific case you can either use a separate method which then calls the original parent method or you can try to use composition (instead of inheritance).
And if worst comes to worst: with 5.4 we could now use traits to overcome that obstacle.

Note: If you want to test your script with E_STRICT in PHP <= 5.3 you need to change your core.php error level:

Configure::write('Error', array(
    'handler' => 'ErrorHandler::handleError',
    'level' =>  E_ALL | E_STRICT, // meaning: E_ALL + E_STRICT (using binary operators)
    'trace' => true
));

How does a overriden method now look like?

It always a good idea to first take a look at the parent class your class inherits from. The method declaration can then easily be copy-and-pasted. This way nothing gets accidently swept under the rug.

A side note: You should also make sure that you call the parent method for callbacks. This is often forgotten and can lead to strange events. This parent method could do something important that would otherwise be missing.

public function initialize(Controller $controller) { 
    parent::initialize($controller); # important call
    // one stuff
}

Concrete examples

The controllers are pretty easy. Except for maybe beforeRedirect the other callbacks don’t have any params:

public function beforeRedirect($url, $status = null, $exit = true) {}

So if we would override this method, we have to use the same declaration.

Helpers are also straight-forward:

public function afterRender($viewFile) {}

public function beforeLayout($layoutFile) {}

More interesting are the components and behaviors, for example. Part of my contribution was adding the overdue type hinting declarations (until now some classes had them, some don’t). All classes that use objects should now have them properly outlined in the method declaration:

// a component (for example my Common component)
public function initialize(Controller $controller) {}

public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {}

// a behavior (for example my Bitmasked behavior)
public function setup(Model $Model, $config = array()) {}

public function afterFind(Model $Model, $results, $primary) {}

public function afterSave(Model $model, $created) {}

public function beforeDelete(Model $model, $cascade = true) {}

If you don’t pass on a model it will trigger an error – which is a good thing. PHP gets more and more type safe this way (and with this closer to languages as JAVA where less mistakes and abuse is possible due to those restrictions).

Hopefully, with those tips, you will be able to get your app E_STRICT compliant. Happy coding! 🙂

Final tips

Coders are lazy! We don’t want to do things manually if we can help it.
It is possible to get some of the necessary changes done via upgrade shell. At least I did it this way. Check it out (cake Upgrade.Correct reference) or write your own shell commands. The huge advantage: Once written you can update as many apps as you want with a single click.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.