In a CakePHP 2.2 app, I’m using class constants in a Model for some internal configuration. The following issue came up.
Short version:
Cake’s lazy class loading will not be triggered by a static call to the Model class.
If the first access to a Model in a Controller is
MyModel::SOME_CONST // fails
the class will be unknown. If any instance of the class is used before, it’s fine:
$this->MyModel->something();
MyModel::SOME_CONST // works
Not knowing about the details of the lazy loading implementation:
Question: Is this something that is impossible to fix? If so, why? How do I then best work around it in my App myself (wrap consts in a function)? Or is there a chance to improve the lazy loading so that it works with static access, too?
Long version with code:
In order to test the different cases, I made a small test App with 1 Model and 1 Controller:
Model/Post.php:
<?php
class Post extends AppModel {
public $useTable = false; // Don't bother with a DB
const FOO = "foo";
public $bar = "bar";
}
Controller/PostsController.php:
<?php
class PostsController extends AppController {
public function constant() {
debug(Post::FOO);
}
public function variable() {
debug($this->Post->bar);
}
public function variableFirst() {
debug($this->Post->bar);
debug(Post::FOO);
}
}
Accessing the three controller actions through the browser, the different cases can now be tested.
1) accessing the Model constant (at /posts/constant):
Error: Class ‘AppModel’ not found
2) accessing the Model variable (at /posts/variable):
‘bar’
3) accessing the Model constant AFTER a variable (at /posts/variable):
‘bar’
‘foo’
lazyloading works with normal class calls as well as static calls IF you correctly approach it.
Correctly means, that you always have to App::uses() all used classes at the top of your file
for AppModel in a model file:
see the core files for details.