One of the neat features of PHP 5.3 (the lowest accepted version of PHP in the 2.0 release of CakePHP) is called late static binding. Late static binding is one of those ideas that is a little hard to grasp but if you play enough with singletons you will inevitably run into a good use for it.
First I will briefly explain what static binding is. Static binding (a.k.a. "early binding") is when during compilation the location of the jump in code (ASM JMP) can be determined with ease and because of this, the compiler simply can give it a location in memory to run. Late static binding allows that resolution to be done when the interpretor hits the line of code during execution. The best example that requires this style is when you need to do inheritance backwards. Sometimes it's useful to write a method in a base class that pulls data from the class that is abstracted from it. Late static binding allows this to happen with the "static" keyword.
Sorry to mention him 3 times in consecutive posts but I really like Felix's stuff especially his post on the topic of reverse routing. He does some really neat things in there, but I think that his Post::url() doesn't take it far enough, I'm lazy and I don't want to write one of those for every damn model. I think this is a perfect place to use late static binding and override in models if its not right. If all your models extend from AppModel it's as simpile as this
In 5.3 it would look something like thisNote: This may not be prefect since I don't yet have any servers running 5.3 when I have a 5.3 server running I'll update this post
class AppModel extends Model {
static $staticName;
public function __construct() {
$args = func_get_args();
call_user_func_array(array($this, 'parent::__construct'), $args);
static::$staicName = $this->name;
}
public static function url ($id = null, $options = array()) {
$name = inflector::underscore(inflector::pluralize(static::$staticName))
if (!isSet($options['action'])) $options['action'] = 'view';
return Router::url(array(
'controller' => $name,
'action' => $options['action'],
$id
));
}
}
?>
Unfortunately though, 5.3 isn't "stable" yet, so until that is the case this little trick won't be available for all models by default in my applications. Some day soon though it will be. Until that day, just change the static url function per class to make it match the proper circumstance. Remember to keep those models fat.
Sincerely,~Andrew Allen
