#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
- 909 reads