Почему позднее статическое связывание не работает с переменными в PHP 5.3?

Начнем с некоторого кода:

class Super {

    protected static $color;

    public static function setColor($color){
        self::$color = $color;
    }

    public static function getColor() {
        return self::$color;
    }

}

class ChildA extends Super { }

class ChildB extends Super { }

ChildA::setColor('red');
ChildB::setColor('green');

echo ChildA::getColor();
echo ChildB::getColor();

Теперь поздняя статическая привязка в PHP 5.3 с использованием ключевого слова static прекрасно работает со статическими методами, поэтому я предположил, что она проделает то же самое со статическими переменными. Ну, кажется, это не так. В приведенном выше примере выводится не «красный», а затем «зеленый», как я сначала ожидал, а «зеленый» и «зеленый». Почему это не работает с переменными, когда работает с методами? Есть ли другой способ добиться ожидаемого эффекта?


person Johan Fredrik Varen    schedule 14.05.2011    source источник


Ответы (1)


Позднее статическое связывание будет работать только для новых определений переменных/методов. Таким образом, в вашем примере свойство $color Super всегда будет изменяться вместо ChildA или ChildB. Чтобы использовать позднее статическое связывание, вам нужно использовать ключевое слово static вместо self. Кроме того, вам необходимо переопределить свойство $color ваших классов ChildA и ChildB:

class Super {

    protected static $color;

    public static function setColor($color){
        // static instead of self
        static::$color = $color;
    }

    public static function getColor() {
        // static instead of self
        return static::$color;
    }

}

class ChildA extends Super {
    protected static $color;
}
class ChildB extends Super {
    protected static $color;
}

ChildA::setColor('red');
ChildB::setColor('green');

echo Super::getColor(); // prints nothing (NULL = ''), expected
echo ChildA::getColor();// prints red
echo ChildB::getColor();// prints green
person Lekensteyn    schedule 14.05.2011
comment
Большое спасибо, Лекенштейн. Это немного портит удобство наследования, но я справлюсь :) - person Johan Fredrik Varen; 14.05.2011
comment
Спасибо, это действительно помогло. Я попал в ту же ловушку; Мне не хватало переопределения переменной в дочерних классах! У вас есть какая-нибудь литература по этому поводу, поскольку я, похоже, пропустил этот жизненно важный фрагмент в документации по PHP. - person Meberem; 15.01.2012