Она не теряет своего значения, B::i()!=C::i() (они наследуются от A, но переменные внутри методов имеют разное значение ($i1!=$i2)). Ну не может терять значение то, что никогда не было инициализировано. Проверьте var_dump'ом.
class A {
public static function i(){
static $i;
var_dump($i);
return $i? $i: $i = new static;
}
function say(){ echo get_class($this) . "\n"; }
}
class B extends A{}
class C extends A{}
B::i()->say();
C::i()->say();
/*
Вывод:
null
B
null
C
*/
Я в прошлом комментарии описался, прошу прощения, естественно имел ввиду переменную $i внутри метода, а не свойство класса.
По-порядку (разбираю второй вариант):
1. Выполняем
B::i()
а). Т.к. $i — не присвоено значение, то при выполнении тернарного оператора NULL, при преобразовании в булев контекст будет равен FALSE. Следовательно $i=new static; Где static — это контекст класса B. Следовательно $i — экземпляр (объект)
класса B.
б). Функция $i->Say(), где $i — объект класса B совершенно логично выполнит get_class($this). Т.е. вернёт имя класса, к которому принадлежит $this — в данном случае B.
2. Выполняем
C::i()
а). Т.к. $i — не присвоено значение (то, что оно помечено статическим — ничего не значит, т.к. по сути B::i() и C::i() не зависят друг от друга в плане инициализации свойств), то при выполнении тернарного оператора NULL, при преобразовании в булев контекст будет равен FALSE. Следовательно $i=new static; Где static — это контекст класса C. Следовательно $i — экземпляр (объект)
класса C.
б). Функция $i->Say(), где $i — объект класса C совершенно логично выполнит get_class(). Т.е. вернёт имя класса, к которому принадлежит $this — в данном случае C.
Перевод: «Псевдо-переменная $this доступна в том случае, если метод был вызван в контексте объекта. $this является ссылкой на вызываемый объект. Обычно это тот объект, которому принадлежит вызванный метод, но может быть и другой объект, если метод был вызван статически из контекста другого объекта.»
Мой мозг не мог провести аналогию с этим абзацем, до того как вы не объяснили причины такого поведения в предыдущем комментарии. Спасибо.
Да, вот именно таблички и не хватает, а жаль. Серьёзно, для меня не было очевидным такое поведение $this. Но это обозначает лишь только, что есть куда развиваться.
Спасибо за разъяснения и приобретённый опыт. Сделаю выводы. Думаю многие, кто читает ваш комментарий и не знают этой особенности также приобретут новые знания. Но всё же, мне кажется, что разработчикам стоило бы задокументировать неочевидное поведение интерпретатора. Ведь если наперёд не знать, что это капризы PHP, то программист, в особенности новичок, может потратить не один час в тщетных поисках ошибки. Зная такую особенность, программисты смогут избегать, а ещё лучше, учитывать это при использовании такого рода конструкций.
Я в прошлом комментарии описался, прошу прощения, естественно имел ввиду переменную $i внутри метода, а не свойство класса.
1. Выполняем
а). Т.к. $i — не присвоено значение, то при выполнении тернарного оператора NULL, при преобразовании в булев контекст будет равен FALSE. Следовательно $i=new static; Где static — это контекст класса B. Следовательно $i — экземпляр (объект)
класса B.
б). Функция $i->Say(), где $i — объект класса B совершенно логично выполнит get_class($this). Т.е. вернёт имя класса, к которому принадлежит $this — в данном случае B.
2. Выполняем
а). Т.к. $i — не присвоено значение (то, что оно помечено статическим — ничего не значит, т.к. по сути B::i() и C::i() не зависят друг от друга в плане инициализации свойств), то при выполнении тернарного оператора NULL, при преобразовании в булев контекст будет равен FALSE. Следовательно $i=new static; Где static — это контекст класса C. Следовательно $i — экземпляр (объект)
класса C.
б). Функция $i->Say(), где $i — объект класса C совершенно логично выполнит get_class(). Т.е. вернёт имя класса, к которому принадлежит $this — в данном случае C.
Надеюсь это то, что вы хотели услышать
Мой мозг не мог провести аналогию с этим абзацем, до того как вы не объяснили причины такого поведения в предыдущем комментарии. Спасибо.
Да, вот именно таблички и не хватает, а жаль. Серьёзно, для меня не было очевидным такое поведение $this. Но это обозначает лишь только, что есть куда развиваться.