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

StackOverflow https://stackoverflow.com/questions/4577187

Вопрос

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

<?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, подробнее о том, что объясняется ниже.)

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

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

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

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

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

Это было полезно?

Решение

Это относится к правильному классу, просто если, если не переоборудован или иным образом, эталонный набор не нарушен, статические свойства в подклассах находятся в том же ссылке, что и в SuperClass.

Итак, вы должны сделать:

class Brother extends Mommy
{
    protected static $_data;
}

или же:

class Brother extends Mommy
{
}

$tmp = null;
Brother::$_data =& $tmp;
unset($tmp);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top