Перегрузка в PHP
http://belarusweb.net
Основы создания сайтов

Перегрузка в PHP

Понятие перегрузки

Под перегрузкой в программировании подразумевается возможность использования функций и методов, имеющих одинаковые имена. Однако в PHP понятие 'перегрузки' интерпретируется не так, как в других объектно-ориентированных языках. В PHP перегрузка означает возможность получения доступа при помощи специальных методов перегрузки, называемых еще магическими или волшебными методами, к недоступным обычными способами свойствам или методам. К таковым относятся свойства и методы, которые не были объявлены или не видны в текущей области видимости. При этом методы перегрузки, объявляемые в текущем классе, должны иметь область видимости public, не могут принимать аргументы по ссылке и вызываются только в случае обращения к указанным свойствам или методам. Перечислим методы перегрузки, имеющиеся в PHP:

Методы перегрузки

Перечислим методы перегрузки, имеющиеся в 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(), то она удаляет переменную, переданную ей в качестве аргумента. К данным функциям мы вернемся во второй части учебника. Теперь же рассмотрим пример 6.20, в котором показаны некоторые ситуации перегрузки свойств.

<?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){
      return isset($this->$name); //возвращаем результат вызова функции isset(),  
	}										 //вызванной для недоступного свойства
	
	public function __unset($name){
      unset($this->$name);  		 //удаляем недоступное свойство 
   }										 
}

$obj_1=new my_class(); 	 			  //Создаем объект класса my_class
			 		 
echo $obj_1->private_var_1.'<br>'; //Выведет 10, что возможно благодаря определенному 
										//в классе методу перегрузки __get()
$obj_1->private_var_1=20; 		//Изменяем значение закрытого свойства вне класса,
										//что возможно благодаря методу перегрузки __set()
echo $obj_1->private_var_1.'<br>';			//Выведет 20

echo isset($obj_1->private_var_1).'<br>'; //Выведет '1', т.е. true
unset($obj_1->private_var_1); //Удаляем закрытое свойство вне класса, что стало
										//возможным благодаря методу перегрузки __unset()
echo isset($obj_1->private_var_1).'<br>'; //Выведет '', т.е. false - свойство удалено

echo $obj_1->private_var_2.'<br>';	//Метод перегрузки __get() выведет сообщение	
$obj_1->private_var_2=5; 		//Устанавливаем значение закрытого св-ва вне класса
echo $obj_1->private_var_2.'<br>';	//Выведет 5					 
					
echo $obj_1->private_var_3.'<br>';	//Метод перегрузки __get() выведет сообщение												 
?> 

Пример 6.20. Перегрузка свойств

Как видим, методы перегрузки позволяют нам получить доступ, например, к приватным и защищенным свойствам, которые в обычных условиях недоступны при обращении к ним вне класса. Однако следует помнить, что перегрузка свойств работает только в контексте объекта, поэтому соответствующие им методы перегрузки не могут быть объявлены статичными и не вызываются при попытке обращения к недоступным статическим свойствам.

Что касается последних двух методов перегрузки, то первый из них предназначен для работы с недоступными методами в контексте объекта, а второй – для работы с недоступными статическими методами (см. пример 6.21).

<?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();  
   }
}

$obj_1=new my_class(); 	 		//Создаем объект класса my_class
			 		 
echo $obj_1->my_func();   		//Выведет строку функции my_func() благодаря 
										//определению в классе метода перегрузки __call()
echo $obj_1::static_func();   //Выведет строку функции my_func() благодаря 
										//наличию метода перегрузки __callStatic()
?> 

Пример 6.21. Перегрузка методов