PHP 5.3: Поздняя статическая привязка не работает для свойств, определенных в родительском классе, но отсутствует в дочернем классе

Взгляните на этот пример и обратите внимание на указанные результаты.

<?php

class Mommy
{
    protected static $_data = "Mommy Data";

    public static function init( $data )
    {
        static::$_data = $data;
    }

    public static function showData()
    {
        echo static::$_data . "<br>";
    }
}

class Brother extends Mommy
{
}

class Sister extends Mommy
{
}

Brother::init( "Brother Data" );
Sister::init( "Sister Data" );

Brother::showData(); // Outputs: Sister Data
Sister::showData(); // Outputs: Sister Data

?>

Насколько я понимаю, использование ключевого слова static будет относятся к дочернему классу, но, по-видимому, волшебным образом применяется к родительскому классу всякий раз, когда он отсутствует в дочернем классе. (Это своего рода опасное поведение для PHP, подробнее об этом рассказывается ниже.)

Я имею в виду следующие две вещи, почему я хочу это сделать:

  1. Я не хочу избыточности определения всех свойств во всех дочерних классах.
  2. Я хочу, чтобы свойства определялись как значения по умолчанию в родительском классе, и я хочу, чтобы определение дочернего класса могло переопределять эти свойства везде, где это необходимо. Дочерний класс должен исключать свойства всякий раз, когда предполагаются значения по умолчанию, поэтому я не определяю свойства в дочерних классах в приведенном выше примере.

Однако, если мы хотим переопределить свойство во время выполнения (через init), он переопределит его для родительского класса! С этого момента дочерние классы, инициализированные ранее (как в случае с Brother), неожиданно изменяются для вас.

По-видимому, это результат того, что дочерние классы не имеют собственной копии статического свойства, если оно не определено явно внутри дочернего класса - но вместо того, чтобы выдавать ошибку, он переключает поведение static на доступ к родительскому классу. Следовательно, Есть ли способ, которым родительский класс может динамически создавать свойство, принадлежащее дочернему классу, не появляясь внутри определения дочернего класса? Таким образом, дочерний класс может иметь свою собственную копию статического свойства и ключевое слово static может относиться к нему должным образом, и его можно написать с учетом значений по умолчанию родительских свойств.

Или есть какое-то другое решение, хорошее, плохое или уродливое?

10
задан j0k 4 September 2012 в 12:00
поделиться