Как я могу создать константу в подклассе для использования в методе, найденном в родительском классе в PHP 5.2? - PullRequest
3 голосов
/ 10 декабря 2010

Изменить:
* Примечание: я использую PHP 5.2 в настоящее время, к сожалению. Я не могу найти приличного дешевого хозяина, предлагающего 5.3 ...


В PHP self относится к классу, в котором определяется вызываемый метод. Это означает, что если вы не переопределите метод в дочернем классе, ключевое слово self будет ссылаться на родительский класс, даже когда вызывается из дочернего класса.

Например, этот код:

<?php

class ParentClass {
  const NAME = "ParentClass";
  public function showName() {
    echo self::NAME . "<br />\n";
  }
}

class ChildClass extends ParentClass {
  const NAME = "ChildClass";
  public function __construct() {
    echo self::NAME . "<br />\n";
  }
}

$test = new ChildClass();
$test->showName();

?>

Создаст этот вывод:

ChildClass
ParentClass

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

Короче говоря, как я могу сделать так, чтобы результат вышеприведенного образца был ...

ChildClass
ChildClass

... без дублирования кода родителя внутри ребенка?

Ответы [ 4 ]

9 голосов
/ 10 декабря 2010

Попробуйте

function showName() {
   return static::NAME;
}

При этом используется поздняя статическая привязка :

Начиная с PHP 5.3.0, PHP реализует функция называется поздние статические привязки который может быть использован для ссылки на называется класс в контексте статического наследование.

Точнее, поздние статические привязки работать, сохраняя класс, названный в последний "переадресация вызова". В случае вызовы статических методов, это класс явно названный (обычно тот, на слева от оператора ::); в случае вызовов не статических методов, это класс объекта. "Переадресация" вызов "является статическим, который введено self ::, parent ::, static ::, или, если идет вверх в классе иерархия, forward_static_call (). функция get_called_class () может быть используется для получения строки с имя вызываемого класса и static :: вводит свою сферу.

РЕДАКТИРОВАТЬ: Для 5.2.x

Если у вас нет 5.3.0, вы не сможете воспользоваться этим. Одно распространенное решение hack состоит в создании статического кэша (например, private static $statics = array()), на который ссылается имя дочернего класса. Это требует, чтобы вы отслеживали наследование объекта, чтобы переопределить значение в __construct, и явно определить, какие статические объекты являются «наследуемыми». Например, SilverStripe использует эту технику в Sapphire ORM, чтобы обойти ограничения статического связывания PHP. Они определяют базовый класс объектов и различные статические функции управления переменными.

5 голосов
/ 10 декабря 2010

Я считаю, что соответствующая синтаксическая соль для вашего случая:

print constant(get_class($this)."::NAME");
1 голос
/ 26 мая 2015

Использование static::CONSTNAME вернет правильное значение.

1 голос
/ 10 декабря 2010

Может быть, это просто из-за вашего короткого примера, но ссылки на "себя" не нужны.

Я бы просто сделал это:

class ParentClass {
  public function showName() {
    echo $this->name() . "<br />\n";
  }

  public static function name() {
    return "ParentClass";
  }
}

class ChildClass extends ParentClass {
  public function __construct() {
    echo $this->name() . "<br />\n";
  }
  public static function name() {
    return "ChildClass";
  }
}

$test = new ChildClass();
$test->showName();

Вывод:

ChildClass
ChildClass
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...