PHP const/static variables not usable in static context by parent class
For some reason (which?), PHP const/static variables defined in a child class are not usable in a static context by the parent class.
Why?
Example 1:
class Model{
function getAll(){
$query = "SELECT * FROM " . self::DATABASE_TABLE_NAME;
// ...
}
}
class Post extends Model{
const DATABASE_TABLE_NAME = 'post';
}
$p = Post::getAll();
When I run tha开发者_如何学Ct I get:
Fatal error: Undefined class constant 'DATABASE_TABLE_NAME' on line 3
(The row with $query = ...)
Example 2:
class Model{
function getAll(){
$query = "SELECT * FROM " . self::$DATABASE_TABLE_NAME;
// ...
}
}
class Post extends Model{
static $DATABASE_TABLE_NAME = 'post';
}
$p = Post::getAll();
Then I get:
Fatal error: Access to undeclared static property: Model::$DATABASE_TABLE_NAME on line 3
(Same row)
PHP5.3 introduced late static binding — that's what you're looking for.
class ParentClass {
public function getAll() {
var_dump('Get all from ' . static::TABLE_NAME);
}
}
class ChildClass extends ParentClass {
const TABLE_NAME = 'my_table_name';
}
$c = new ChildClass();
$c->getAll(); // Get all from my_table_name
EDIT:
However you should design your classes a little bit different. The above solution relies on language dynamics (you can refer to something (eg. a class constant) that doesn't even exists). In such a simple example everything is fine but in real word cases this leads to producing horrible and hard to maintain code.
It'd be better to force the delivered class (ChildClass) to implement some method that returns table name:
abstract class ParentClass {
// getAll function
abstract protected function getTableName();
}
class ChildClass extends ParentClass {
// You have to implement this method
protected function getTableName() {
return 'table name';
}
}
I found the answer here: How can I get the classname from a static call in an extended PHP class?
Solution:
class Model{
function getAll(){
$class = get_called_class();
$query = "SELECT * FROM " . $class::$DATABASE_TABLE_NAME;
// ...
}
}
class Post extends Model{
static $DATABASE_TABLE_NAME = 'post';
}
$p = Post::getAll();
There all available.
Under the static context you should be using late static binding so that the code would become:
$query = "SELECT * FROM " . static::$DATABASE_TABLE_NAME;
i would also advise you to use constants for sanity reasons.
加载中,请稍侯......
精彩评论