Задачка с собеседования
В каждом языке есть свои примечательные особенности. Некоторые из них могут подпортить жизнь при отладке, другие могут позволить делать невозможное возможным. В PHP есть так же свои особенности и часто про эти особенности любят спрашивать на собеседованиях. Одна из таких задачек:
<?php
class Foo
{
private $prop = 'Hello!';
public function show($obj)
{
echo $obj->prop;
}
}
$obj = new Foo();
$obj->show( new Foo() );
Как выполнится этот код?
Размышляем… Мы пытаемся вызвать приватное свойство у объекта. По логике должна быть ошибка. Чтобы это было проще для понимания, сделаем такой код и выполним:
class Bar extends Foo
{
function __construct()
{
var_dump( $this->prop );
}
}
$obj = new Bar;
Вывод:
Notice: Undefined property: Bar::$prop in /in/t8CFo on line 23 NULL
Согласно принципам инкапсуляции наше приватное свойство скрыто даже от наследника. Выходит, что по логике, если выполнить код:
$obj2 = new Bar;
$obj1 = new Foo;
var_dump( $obj2->prop );
// Notice: Undefined property: Bar::$prop in /in/nPWa6 on line 31 NULL
var_dump( $obj1->prop );
// Fatal error: Uncaught Error: Cannot access private property Foo::$prop in /in/nPWa6:32 Stack trace:
Все работает корректно.
Но если мы напишем такой код:
( new Foo )->show( new class extends Foo { } );
Вдруг выясняется что мы получаем ответ:
string(6) "Hello!"
И вот это и есть особенность PHP. Если вы вызываете приватное свойство объекта от класса внутри методов этого класса, то приватное свойство будет доступно. И если мы возьмем пример, который был задан на собеседовании в самом начале:
( new Foo )->show( new Foo );
То так же выведется значение приватного свойства.
Итого
Это особенность PHP, про которую нужно знать чтобы не наступить на грабли. В методах класса можно получить доступ к приватным свойствам у экземпляра класса, созданного от этого класса. И конкретно про эту особенность и другие, вас могут спросить на собеседовании на вакансию PHP разработчика.
Все примеры можно проверить на всех версиях интерпретаторов прямо онлайн https://3v4l.org/PE1EV