#7. 8 php ООП Перехват обращений к членам класса
Primary tabs
При обращении к несуществующим или недоступным из данной части программы свойствам и методам класса, имеется возможность перехватить такие обращения и выполнить какие-то действия. Для этого предназначены специальные методы, которые должны быть реализованы в классе:
- Метод
__get
вызывается каждый раз, когда мы пытаемся обратиться к несуществующему или недоступному свойству для его чтения, и принимает в качестве аргумента имя этого свойства. Например, при попытке получить и вывести на экран значение private-свойстваproperty
:<?php class Example { private $property; public function __get($name) { echo "Свойство объекта '$name' не существует или не доступно для чтения"; } } obj = new Example; echo obj->property;
будет выведено сообщение:
Свойство объекта 'property' не существует или не доступно для чтения
- Метод
__set
вызывается при установке значения несуществующего или недоступного свойства и принимает в качестве аргумента имя свойства$name
и значение$value
:<?php class Example { private $property; public function __set($name, $value) { echo "Свойство объекта '$name' не существует или не доступно для записи"; } } $obj = new Example; $obj->property = 10;
Так как мы попытались установить значение недоступного свойства
property
, то в результате выполнения последней строки будет вызван метод__set
, который выведет соответствующее сообщение:Свойство объекта 'property' не существует или не доступно для записи
- Наконец, метод
__call
вызывается при обращении к несуществующему/недоступному методу. Он получает на вход имя вызываемого метода и список передаваемых параметров:<?php class Example { private $property; public function __call($name, $args) { echo "Метод '$name' не существует или не доступен"; } } $obj = new Example; $obj->set_property(10);
Результатом выполнения примера будет сообщение о том, что метод "set_property" не существует или не доступен.
Описанные выше методы используются для динамического создания свойств и методов класса. В примере 1 для хранения динамически созданных свойств объекта $lion
используется ассоциативный массив $vars
.
Пример 1. Динамические свойства
<?php class Animal { private $name; private $vars; public function __construct($text) { $this->name = $text; $this->vars = []; } public function __get($name) { echo "Перехват: чтение значения свойства '$name'<BR>"; return isset($this->vars[$name]) ? $this->vars[$name] : null; } public function __set($name, $value) { echo "Перехват: установка значения свойства '$name' в значение '$value'<BR>"; return $this->vars[$name] = $value; } public function __call($name, $args) { echo "Перехват вызова незарегистрированного метода '$name'<BR>"; } public function get_name() { return $this->name; } } $lion = new Animal("Бонифаций"); $lion->age = 5; $lion->name = "Симба"; echo $lion->age, "<BR>"; echo $lion->name, "<BR>"; echo "Используем 'get_name()' для получения имени<BR>"; echo $lion->get_name(), "<BR>"; echo $lion->get_age();
При установке несуществующего свойства age
:
$lion->age = 5;
соответствующий элемент добавляется в массив $vars
, и его значение мы получаем далее при чтении свойства age
:
echo $lion->age;
При попытке установки значения свойства $name
:
$lion->name = "Симба";
объявленного как private, добавляется элемент массива $vars
с одноименным индексом "name", значение которого мы и получим, обратившить к свойству name
объекта $lion
напрямую для чтения:
echo $lion->name;
Если же мы используем метод get_name
, описанный в классе, для получения имени, то получим значение private-свойства name
.
Обратившись к несуществующему методу объекта:
$lion->get_age()
получим сообщение о том, что произошел перехват данного вызова.
Результат выполнения примера:
Замечание: Динамическое создание свойств по умолчанию
Если в классе не будет описан метод __set
, то по умолчанию при попытке присвоить значение несуществующему свойству объекта PHP автоматически создаст соответствующее свойство. Например, в результате выполнения кода,
$lion = new Animal("Бонифаций"); $lion->age = 5; echo "Льву по имени ", $lion->get_name(), " ", $lion->age, " лет<BR>";
даже если методы __set
и __get
не описаны, получим строку:
Льву по имени Бонифаций 5 лет.
Однако, начиная с PHP 8.2.0, такой подход считается устаревшим, и для работы с произвольными именами свойств класс должен реализовать описанные выше специальные методы. Если все же предполагается использование динамических свойств, то класс нужно пометить атрибутом AllowDynamicProperties
- Log in to post comments
- 487 reads