Статические переменные PHP в абстрактном родительском классе: вопрос находится в примере кода!
Быстрый код с включенным вопросом:
abstract class ClassParent {
public static $var1 = "ClassParent";
}
class ClassChild1 extends ClassParent{
public static function setvar1(){
ClassChild1::$var1 = "ClassChild1";
}
}
class ClassChild2 extends ClassParent{
public static function setvar1(){
ClassChild2::$var1 = "ClassChild2";
}
}
ClassChild1::setvar1();
echo ClassChild2::$var1;
// Returns "ClassChild1". Shouldn't this still be "ClassParent"?
Я предполагаю, что вышесказанное является ожидаемым поведением, а не ошибкой PHP. В этом случае, как я могу объявить статическую переменную в родительском классе, которая будет обрабатываться отдельно для дочерних классов. Другими словами, я хочу иметь отдельные статические значения PER CHILD CLASS. Должен ли я объявлять статическую переменную конкретно в дочерних классах или есть ли другой способ?
Спасибо!
Ответы
Ответ 1
РЕДАКТИРОВАТЬ: При дальнейшем расследовании я думаю, что то, что вы просите, прямо не возможно, даже с поздним статическим привязкой. На самом деле, я немного удивлен.
Ответ на этот вопрос дает некоторые обходные пути.
Оригинальный ответ:
В родительском классе, если вы ссылаетесь на статическую переменную в форме:
self::$var
Он будет использовать эту же переменную во всех унаследованных классах (так что все дочерние классы будут по-прежнему обращаться к переменной в родительском классе).
Это связано с тем, что привязка для ключевого слова self
выполняется во время компиляции, а не во время выполнения.
Как и в PHP 5.3, PHP поддерживает позднюю статическую привязку, используя ключевое слово static
. Итак, в ваших классах обратитесь к переменной с помощью:
static::$var
И "статический" будет разрешен дочернему классу во время выполнения, поэтому для каждого дочернего класса будет отдельная статическая переменная.
Ответ 2
Спасибо за этот вопрос! У меня были некоторые проблемы, которые я не мог отслеживать, и это помогло мне решить их.:)
Вам может быть интересно узнать, что существует отчет об ошибках для такого поведения, которое включает обходной путь. В вашем случае это будет:
class ClassChild1 extends ClassParent{
public static function setvar1(){
$tmp = 'x';
static::$var1 =& $tmp; // break reference
// and now this works as expected: (changes only ClassChild1::$var1)
static::$var1 = "ClassChild1";
}
}
// do the same in ClassChild2...
Уродливо, черт возьми, я согласен, но PHP работает так, как ожидалось, плюс он не имеет побочных эффектов.
Это действительно очень сомнительная (и плохо документированная) "особенность" в моих глазах - пусть надеется, что они когда-нибудь меняются.