PHP 5.3: Позднее статическое связывание не работает для свойств, если определить в родительском классе, отсутствуя в детском классе
-
14-10-2019 - |
Вопрос
Взгляните на этот пример и обратите внимание на указанные выходы.
<?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
?>
Я понимаю, что использование статический Ключевое слово будет относиться к классу ребенка, но, по -видимому, оно волшебным образом относится к родительскому классу, когда он отсутствует в детском классе. (Это своего рода опасное поведение для PHP, подробнее о том, что объясняется ниже.)
Я имею в виду следующие две вещи, почему я хочу это сделать:
- Я не хочу избыточности определения всех свойств во всех классах детей.
- Я хочу, чтобы свойства определялись как по умолчанию в родительском классе, и я хочу, чтобы определение класса дочернего класса имело возможность переопределить эти свойства, где это необходимо. Детский класс должен исключать свойства всякий раз, когда предназначены дефолты, поэтому я не определяю свойства в классах дочерних классов в приведенном выше примере.
Однако, если мы хотим переопределить свойство во время выполнения (с помощью метода инициации), оно будет переопределить его для родительского класса! С этого момента занятия ребенка инициализировались ранее (как в случае брата) неожиданно меняются на вас.
Очевидно, это результат того, что классы детей не имеют собственной копии статического свойства, когда оно явно не определено внутри детского класса-но вместо того, чтобы бросить ошибку, она переключает поведение статический Чтобы получить доступ к родителю. Следовательно, Есть ли какой -то способ, которым родительский класс может динамически создать свойство, которое принадлежит детске классу, не появляясь внутри определения класса ребенка? Таким образом, урок детского класса может иметь свою собственную копию статического свойства, и статическое ключевое слово может соответствовать ему должным образом, и его можно записано, чтобы принять во внимание дефолт имущества родителей.
Или есть другое решение, хорошее, плохое или уродливое?
Решение
Это относится к правильному классу, просто если, если не переоборудован или иным образом, эталонный набор не нарушен, статические свойства в подклассах находятся в том же ссылке, что и в SuperClass.
Итак, вы должны сделать:
class Brother extends Mommy
{
protected static $_data;
}
или же:
class Brother extends Mommy
{
}
$tmp = null;
Brother::$_data =& $tmp;
unset($tmp);