Доброго дня.
Представим следующий код:
class A {
private $property = 'A';
public function get() {
echo $this->property;
// если тут сделать var_dump($this),
// будет видно, что $this указывает на инстанс B,
// который привязан к переменной $b, создающей контекст.
// Проверим это, вызвав свойство, отсутствующее в классе A.
// PHP не перенаправляет вызовы от родителя к потомку, т.к.
// это противоречит самой концепции наследования.
echo $this->non_inherited;
}
}
class B extends A {
public $property = 'B';
public $non_inherited = 'B';
}
$b = new B;
$b->get(); // выведет AB, ожидается BB
Он работает не так, как ожидается. Я вызываю метод в контексте класса
B, однако, поскольку его не существует явно, вызов с информацией о контексте передается в родительский класс
A (именно поэтому $this в классе A указывает на B, а не на A). Ожидается, что будет вызвана публичное свойство
B->property, которое имеется в классе
B, однако вместо этого, по каким-то причинам, из контекста B я получаю доступ к приватному свойству класса
A. Причем если я попробую вызвать свойство, которое есть только в
B (B->non_inherited), оно будет выведено, из чего следует, что запрос первоначально все-таки идет к классу
B, однако по каким-то причинам PHP резольвит его в пользу
A.
Если изменить private в
A на public, все будет работать так, как ожидается.
Выглядит так, будто приватные свойства родителей имеют более высокий приоритет, нежели публичные свойства потомков.
Дамп инстанса показывает, что имеются оба свойства, и приватное, и публичное.
Почему так происходит, с технической точки зрения, каковы причины и логика такого поведения? Подозреваю, что это связано с внутренним представлением приватных \ публичных свойств. Возможно, вопрос очевиден, но я с таким столкнулся впервые, т.к. данный пример никогда не применить в реальных проектах, сохранив руки не оторванными)
Заранее спасибо.