Перезагрузка в php
Перезагрузка в php
Перезагрузка в php позволяет автоматически создавать свойства и методы. Эти динамические сущности обрабатываются с помощью магических методов, которые можно создать в классе для различных видов действий
Традиционно перегрузка означает возможность иметь несколько одноимённых методов с разным количеством и типами аргументов
Для php перезагрузка позволяет получать доступ к свойствам и методам недостпных обычными способами
Для перезагрузки используются магические методы
К методам и свойствам недоступных обычными способами относятся сущности которые не были объявлены или не видны в текущей области видимости
Все метды перезагрузки должны быть объявлены как public
Для аргументов магических методов не должны использоваться ссылки
Свойства и метода доступные, которые используются в php для перезагрузки перечислены в официальной документации
https://www.php.net/manual/ru/language.oop5.overloading.php
Например public __set(string $name, mixed $value): void будет выполнен при записи данных в недоступные (защищённые или приватные) или несуществующие свойства
Аргумент $name представляет собой имя вызываемого свойства. Метод __set() содержит аргумент $value, представляющий собой значение, которое будет записано в свойство с именем $name
Перегрузка свойств работает только в контексте объекта. Данные магические методы не будут вызваны в статическом контексте. Поэтому эти методы не должны объявляться статическими. При объявлении любого магического метода как static будет выдано предупреждение.
PHP не будет вызывать перегруженный метод изнутри того же перегруженного метода. Это означает, что, например, написание return $this->foo внутри __get() вернёт null и вызовет ошибку уровня E_WARNING
class PropertyTest
{
#Место хранения перегружаемых данных
private $data = array();
#Перезагрузка не применяется к объявленным свойствам
public $declared = 1;
#Здесь перезагрузка будет использована только при доступе не класса
private $hidden = 2;
public function __set($name, $value)
{
echo "Установка '$name в $value'<br>";
$this->data[$name] = $value;
}
public function __get($name)
{
echo "Получение переменной '$name' <br>";
#Функция array_key_exists проверяет присутствие указанного ключа в массиве
if (array_key_exists($name, $this->data))
{
return $this->data[$name];
}
#debug_backtrace — Генерирует стек вызовов функций и может использоваться для отладки
$trace = debug_backtrace();
#Trigger_error — это функция в PHP, которая вызывает пользовательскую ошибку, предупреждение или уведомление
trigger_error(
'Неопределённое свойство в __get(): ' . $name .
' в файле ' . $trace[0]['file'] .
' на строке ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
}
#isset — Определяет, объявили ли переменную и отличается ли её значение от null
#Метод __isset() будет выполнен при использовании isset() или empty() на недоступных (защищённых или приватных) или несуществующих свойствах
public function __isset($name)
{
echo "Установлено ли '$name' ?
";
return isset($this->data[$name]);
}
public function __unset($name)
{
echo "Уничтожение переменной '$name'<br>";
unset($this->data[$name]);
}
#Не магический метод, просто для примера
public function getHidden()
{
return $this->hidden;
}
}
$obj1 = new PropertyTest();
$obj1->test = 10;
echo $obj1->test;
echo "<br>";
var_dump(isset($obj1->test));
echo "<br>";
unset($obj1->test);
var_dump(isset($obj1->test));
echo "<br>";
echo $obj1->declared;
echo "<br>";
echo "Закрытые свойства видны внутри класса, поэтому __get() не используется...<br>";
echo $obj1->getHidden();
echo "<br>";
echo "Закрытые свойства не видны вне класса, поэтому __get() используется...<br>";
echo $obj1->hidden;
Установка 'a' в '1'
Получение 'a'
1
Установлено ли 'a'?
bool(true)
Уничтожение 'a'
Установлено ли 'a'?
bool(false)
1
Давайте поэкспериментируем с закрытым свойством 'hidden':
Закрытые свойства видны внутри класса, поэтому __get() не используется...
2
Закрытые свойства не видны вне класса, поэтому __get() используется...
Получение 'hidden'
Notice: Неопределённое свойство в __get(): hidden в <file> on line 70 in <file> on line 29
Перезагрузка методов
__call() запускается при вызове недоступных методов в контексте объект
__callStatic() запускается при вызове недоступных методов в статическом контексте
Аргумент $name представляет собой имя вызываемого метода. Аргумент $arguments представляет собой нумерованный массив, содержащий параметры, переданные в вызываемый метод $name
class MethodTest
{
public function __call($name, $arguments)
{
echo "Вызов метода '$name' " . implode(', ', $arguments) . '<br>';
}
// implode - это встроенная функция предназначенная для объединения элементов массива в строку с использованием определенного разделителя
public static function __callStatic($name, $arguments)
{
echo "Вызов статического метода '$name' " . implode(', ', $arguments). "<br>";
}
}
$obj1 = new MethodTest();
$obj1->testRun('В контексте объекта');
$obj1::runFunc('В статическом контексте');
#Результат
#Вызов метода 'testRun' В контексте объекта
#Вызов статического метода 'runFunc' В статическом контексте
Итераторы объекта
Объявлять объекты в php можно таким способом, который позволяет пройти по списку элементов данного объекта с помощью оператора foreach. По умолчанию в цикле будут учавствовать все видимые свойства объекта
$class = new MyClass();
foreach($class as $key => $value) {
print "$key => $value\n";
}
Источники
Связанные темы
Оператор разрешения видимости в php
Позднее статическое связывание
Методы создания экземпляра класса в php
Автоматическая загрузка классов
Наследование с помощью extends в php
Конструкторы и деструкторы в php