Подтвердить что ты не робот

Статические переменные 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. Должен ли я объявлять статическую переменную конкретно в дочерних классах или есть ли другой способ?

Спасибо!

4b9b3361

Ответ 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 работает так, как ожидалось, плюс он не имеет побочных эффектов.

Это действительно очень сомнительная (и плохо документированная) "особенность" в моих глазах - пусть надеется, что они когда-нибудь меняются.