PHP :: Перегрузка
Понятие перегрузки
Под перегрузкой в программировании подразумевается возможность использования функций и методов, имеющих одинаковые имена. Однако в PHP понятие «перегрузки» интерпретируется не так, как в других объектно-ориентированных языках. В PHP перегрузка означает возможность получения доступа при помощи специальных методов перегрузки, называемых еще магическими или волшебными методами, к недоступным обычными способами свойствам или методам. К таковым относятся свойства и методы, которые не были объявлены или не видны в текущей области видимости. При этом методы перегрузки, объявляемые в текущем классе, должны иметь область видимости public, не могут принимать аргументы по ссылке и вызываются только в случае обращения к указанным свойствам или методам.
Методы перегрузки
Перечислим методы перегрузки, имеющиеся в PHP:
- __set($name, $value) – выполняется при записи данных в недоступные свойства; здесь аргумент $name представляет собой имя вызываемого свойства, а $value – значение, которое будет записано в данное свойство;
- __get($name) – выполняется при чтении данных из недоступных свойств; здесь аргумент $name представляет собой имя вызываемого свойства;
- __isset($name) – выполняется при использовании функций isset() или empty() на недоступных свойствах; здесь аргумент $name представляет собой имя вызываемого свойства;
- __unset($name) – выполняется при вызове unset() на недоступном свойстве; здесь аргумент $name представляет собой имя вызываемого свойства;
- __call($name, $arguments) – вызывается в контексте объекта при вызове недоступных методов; здесь аргумент $name представляет собой имя вызываемого метода, $arguments – числовой массив, содержащий параметры, передаваемые вызываемому методу;
- __callStatic($name, $arguments) – вызывается в статическом контексте при вызове недоступных методов; здесь аргумент $name представляет собой имя вызываемого метода, $arguments – числовой массив, содержащий параметры, передаваемые вызываемому методу.
Отметим, что функция isset(), определяет установлена ли переменная, переданная ей в качестве аргумента, значением отличным от null, а функция empty() проверяет, считается ли переменная пустой (переменная считается пустой, если она не существует или её значение равно false). Что касается функции unset(), то она удаляет переменную, переданную ей в качестве аргумента. К данным функциям мы вернемся во второй части учебника. Теперь же рассмотрим пример №1, в котором показаны некоторые ситуации перегрузки свойств.
<?php class my_class{ //К доступным свойствам перегрузка не применяется public $var_1=5; //В отношении закрытых свойств методы перегрузки private $private_var_1=10; //вызываются только при доступе вне класса, //где они недоступны обычными способами private $private_var_2; //Метод автоматически вызывается в случае обращения к недоступным свойствам public function __set($name, $value){ //Устанавливаем значение недоступного свойства $this->$name=$value; } //Метод возвращает значение недоступного свойства, если оно установлено, или //выводит сообщение, если такого свойства нет или оно не инициализировано public function __get($name){ //Если переменная установлена значением отличным от null if(isset($this->$name)){ //возвращаем значение недоступного свойства return $this->$name; }else{ echo "Свойство {$name} отсутствует или не определено в данном классе."; } } public function __isset($name){ //возвращаем результат вызова функции isset() //вызванной для недоступного свойства return isset($this->$name);, } public function __unset($name){ //удаляем недоступное свойство unset($this->$name); } } //Создаем объект класса my_class $obj_1=new my_class(); //Выведет 10, что возможно благодаря определенному в классе методу перегрузки __get() echo $obj_1->private_var_1.'<br>'; //Изменяем значение закрытого свойства вне класса, //что возможно благодаря методу перегрузки __set() $obj_1->private_var_1=20; //Выведет 20 echo $obj_1->private_var_1.'<br>'; //Выведет '1', т.е. true echo isset($obj_1->private_var_1).'<br>'; //Удаляем закрытое свойство вне класса, что стало //возможным благодаря методу перегрузки __unset() unset($obj_1->private_var_1); //Выведет '', т.е. false - свойство удалено echo isset($obj_1->private_var_1).'<br>'; //Метод перегрузки __get() выведет сообщение echo $obj_1->private_var_2.'<br>'; //Устанавливаем значение закрытого свойства вне класса $obj_1->private_var_2=5; //Выведет 5 echo $obj_1->private_var_2.'<br>'; //Метод перегрузки __get() выведет сообщение echo $obj_1->private_var_3.'<br>'; ?>
Пример №1. Перегрузка свойств
Как видим, методы перегрузки позволяют нам получить доступ, например, к приватным и защищенным свойствам, которые в обычных условиях недоступны при обращении к ним вне класса. Однако следует помнить, что перегрузка свойств работает только в контексте объекта, поэтому соответствующие им методы перегрузки не могут быть объявлены статичными и не вызываются при попытке обращения к недоступным статическим свойствам.
Что касается последних двух методов перегрузки, то первый из них предназначен для работы с недоступными методами в контексте объекта, а второй – для работы с недоступными статическими методами (см. пример №2).
<?php class my_class{ //Определяем частный метод private function my_func(){ echo 'Получен доступ к частной функции!'.'<br>'; } //Определяем статический частный метод private static function static_func(){// echo 'Получен доступ к статической частной функции!'.'<br>'; } //Определяем метод перегрузки public function __call($name, $arguments){ $this->my_func(); } //Определяем метод перегрузки в статическом контексте public static function __callStatic($name, $arguments){ self::static_func(); } } //Создаем объект класса my_class $obj_1=new my_class(); //Выведет строку функции my_func() благодаря //определению в классе метода перегрузки __call() echo $obj_1->my_func(); //Выведет строку функции my_func() благодаря //наличию метода перегрузки __callStatic() echo $obj_1::static_func(); ?>
Пример №2. Перегрузка методов