Константные / статические переменные PHP не могут использоваться в статическом контексте родительским классом - PullRequest
3 голосов
/ 16 февраля 2011

По какой-то причине (что?) PHP константные / статические переменные, определенные в дочернем классе, не могут использоваться родительским классом в статическом контексте.

Почему?

Пример 1:

class Model{
  function getAll(){
    $query = "SELECT * FROM " . self::DATABASE_TABLE_NAME;
    // ...
  }
}

class Post extends Model{
  const DATABASE_TABLE_NAME = 'post';
}

$p = Post::getAll();

Когда я запускаю это, я получаю:

Fatal error: Undefined class constant 'DATABASE_TABLE_NAME' on line 3 

(строка с $ query =...)

Пример 2:

class Model{
    function getAll(){
        $query = "SELECT * FROM " . self::$DATABASE_TABLE_NAME;
        // ...
    }
}

class Post extends Model{
    static $DATABASE_TABLE_NAME = 'post';
}

$p = Post::getAll();

Тогда я получаю:

Fatal error: Access to undeclared static property: Model::$DATABASE_TABLE_NAME on line 3

(та же строка)

Ответы [ 3 ]

5 голосов
/ 16 февраля 2011

В PHP5.3 введено поздняя статическая привязка - это то, что вы ищете.

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

РЕДАКТИРОВАТЬ:

Однако вы должны разработать свойклассы немного разные.Приведенное выше решение основано на динамике языка (вы можете ссылаться на что-то (например, константу класса), которой даже не существует).В таком простом примере все в порядке, но в реальных случаях это приводит к созданию ужасного и сложного в обслуживании кода.

Было бы лучше заставить поставленный класс (ChildClass) реализовать некоторый метод, которыйвозвращает имя таблицы:

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';
    }
}
2 голосов
/ 16 февраля 2011

Я нашел ответ здесь: Как я могу получить имя класса из статического вызова в расширенном классе PHP?

Решение:

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();
0 голосов
/ 16 февраля 2011

Там все доступно.

В статическом контексте вы должны использовать позднюю статическую привязку , чтобы код стал:

$query = "SELECT * FROM " . static::$DATABASE_TABLE_NAME;

Я бы также посоветовалиспользовать константы по соображениям здравомыслия.

...