Часы работы

Понедельник - Пятница, с 10 до 18
(по Московскому времени)

Контакты

Telegram: https://t.me/devilcode_ru
E-mail: [email protected]

ГлавнаяДелимся опытом и идеямиШпаргалка по магическим методам PHP
Полезная информация

Шпаргалка по магическим методам PHP

8 августа 2023 года

В этой статье вы найдете краткое описание всех магических методов, доступных в PHP. Независимо от того, являетесь ли вы опытным PHP-разработчиком, или начинающим, – если вам приходилось иметь дело с объектно-ориентированным программированием на PHP, вы уже сталкивались, по крайней мере, с некоторыми из магических методов.

Если же вы раньше не слышали об этих методах, позвольте мне их представить. Следующие PHP-функции называются магическими:

  • __construct()
  • __destruct()
  • __call()
  • __callStatic()
  • __get()
  • __set()
  • __isset()
  • __unset()
  • __sleep()
  • __wakeup()
  • __toString()
  • __invoke()
  • __set_state()
  • __clone()
  • __debugInfo()

Названия этих функций зарезервированы – если вы дадите своей собственной функции одно из этих названий, функциональность магического метода будет ассоциироваться с вашим методом. Все магические методы должны объявляться как общедоступные.

Магическими эти методы называются по той причине, что они вызываются автоматически, если вы определите один из этих методов в классе. Вам остается лишь определить, какую задачу будет выполнять метод. Лучший пример – функция __construct(), которая вызывается автоматически каждый раз при создании экземпляра объекта.

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

Магические PHP методы

Далее мы кратко рассмотрим все магические методы, доступные в языке программирования PHP.

Метод __construct()

При определении этого метода в классе, функция будет автоматически вызываться во время создания каждого экземпляра класса. Назначение метода – передача объекту начальных параметров, используемых по умолчанию. Этот метод иногда называют конструктором (constructor).

Вот пример использования этого метода:

<?php
class Student {
    private $name;
    private $email;
 
    public function __construct($name, $email) 
    {
        $this->name = $name;
        $this->email = $email;
    }
}
 
$objStudent = new Student('John', '[email protected]');
?>

В данном примере во время создания нового объекта с параметрами new student('John','[email protected]'), происходит первый вызов метода __construct(). С помощью __construct() мы передаем объекту значения для некоторых из его свойств. 

Метод __destruct()

Метод __destruct() называется деструктором, и вызывается во время уничтожения объекта. Обычно это происходит после остановки или завершения скрипта. Назначение метода – предоставить разработчику возможность сохранить состояние объекта или выполнить какое-то другое действие, следующее за завершением сценария.

Вариант использования:

<?php
class Student {
    private $name;
    private $email;
 
    public function __construct($name, $email) 
    {
        $this->name = $name;
        $this->email = $email;
    }
 
    public function __destruct() 
    {
        echo 'Вызывается во время уничтожения объекта...';
        // сохранение состояния объекта или другие действия
    }
}
 
$objStudent = new Student('John', '[email protected]');
?>

Метод __set()

Магический метод __set() вызывается при попытке присвоить данные недоступным или несуществующим свойствам объекта. Назначение этого метода – задание дополнительных данных объекта, для которых вы явно не определили свойства.

Метод работает следующим образом:

<?php
class Student {
    private $data = array();
 
    public function __set($name, $value) 
    {
        $this->data[$name] = $value;
    }
}
 
$objStudent = new Student();
 
// вызов  __set() 
$objStudent->phone = '0491 570 156';
?>

В приведенном примере мы попытались задать значение несуществующего свойства phone. В результате происходит вызов __set(). В качестве первого аргумента метода __set() выступает название задаваемого свойства, вторым аргументом выступает значение для этого свойства. 

Метод __get()

Если __set() используется для задания значений несуществующих свойств, то __get() выполняет противоположную функцию. Этот метод вызывается в случае, если код пытается считать данные из несуществующих или недоступных свойств объекта. Назначение метода – предоставить значения таким свойствам.

На практике это выглядит следующим образом:

<?php
class Student {
    private $data = array();
 
    public function __set($name, $value) 
    {
        $this->data[$name] = $value;
    }
 
    public function __get($name) 
    {
        If (isset($this->data[$name])) {
            return $this->data[$name];
        }
    }
}
 
$objStudent = new Student();
 
//  вызов __set() 
$objStudent->phone = '0491 570 156';   
 
//вызов  __get() 
echo $objStudent->phone;                      
?>

Метод __toString()

Позволяет определить, что именно вы хотите вывести на экран в том случае, если объект обрабатывается, как строка. К примеру, если вы не применяли метод __toString() для объекта, который используется echo или print, возникнет ошибка.

Рассмотрим на примере:

<?php
class Student {
    private $name;
    private $email;
 
    public function __construct($name, $email) 
    {
        $this->name = $name;
        $this->email = $email;
    }
 
    public function __toString()
    {
        return 'Student name: '.$this->name
        . '<br>'
        . 'Student email: '.$this->email;
    }
}
 
$objStudent = new Student('John', '[email protected]');
echo $objStudent;
?>

Здесь во время вывода echo объект $objStudent вызывает метод __toString(). Внутри этого метода мы определили, что именно мы хотим вывести на экран. Если бы мы этого не сделали, во время исполнения кода произошла бы ошибка. 

Методы __call() и __callStatic()

Если методы __get() и __set() используются в случае обращения к несуществующим свойствам, то метод __call() вызывается при попытке использования недоступных методов, которые вы еще не определили в своем классе. 

<?php
class Student {
    public function __call($methodName, $arguments) 
    {
        // $methodName = getStudentDetails
        // $arguments = array('1')
    }
}
 
$objStudent = new Student();
$objStudent->getStudentDetails(1);
?>

Как можно заметить, в приведенном выше примере мы пытаемся вызвать метод getStudentDetails, который еще не определен, что приводит к вызову __call(). В качестве первого аргумента выступает название вызываемого метода, второй аргумент состоит из списка значений, передаваемых методу.

Метод __callStatic() очень похож на __call(), за единственным исключением: он вызывается в случае обращения к несуществующим методам в статическом контексте. Таким образом, если вы пытаетесь обратиться к неопределенному статическому объекту – воспользуйтесь __callStatic().

Методы __isset() и __unset()

Магический метод __isset() вызывается в случае, если код использует isset() для обращения к несуществующим (или недоступным) свойствам объекта. Посмотрим, как это выглядит на практике: 

<?php
class Student {
    private $data = array();
 
    public function __isset($name) 
    {
        return isset($this->data[$name]);
    }
}
 
$objStudent = new Student();
echo isset($objStudent->phone);
?>

В этом фрагменте свойство phone не определено в объекте, что приводит к вызову метода __isset().

Метод __unset(), в свою очередь, вызывается в том случае, если выполняется вызов unset() для свойств объекта, которые в данный момент не определены или недоступны.

Методы __sleep() и __wakeup()

Магический метод __sleep() отличается от функций, которые мы рассматривали до этого момента. Он вызывается во время обращения к объекту с помощью функции serialize(). В случае очень большого объекта требуется сохранить лишь выбранные свойства во время сериализации и после этого закрыть объект. Метод __sleep() в таком случае возвращает массив с именами всех свойств объекта, которые должны быть сериализированы (преобразованы в специальную строку).

Посмотрим, как можно применить этот метод:

<?php
class Student {
    private $name;
    private $email;
    private $phone;
    private $db_connection_link;
 
    public function __construct($name, $email, $phone) 
    {
        $this->name = $name;
        $this->email = $email;
        $this->phone = $phone;
    }
 
    public function __sleep()
    {
        return array('name', 'email', 'phone');
    }
 
    public function __wakeup()
    {
        $this->db_connection_link = your_db_connection_function();
    }
}
?>

В данном примере во время получения данных из объекта Student, он вызывает метод __sleep(). В результате сохраняются только нужные значения переменных – имя, адрес электронной почты, номер телефона (name, email, phone).

С другой стороны, магический метод __wakeup() используется для восстановления связей с объектами и выполнения заданий после того, как передача данных (сериализация) закончена и для объекта вызывается функция unserialize().

Метод __invoke()

Это особый метод – он используется в том случае, когда объект вызывается в качестве функции. Сначала мы посмотрим, как __invoke() работает, а затем обсудим его назначение. 

<?php
class Student {
    private $name;
    private $email;
 
    public function __construct($name, $email) 
    {
        $this->name = $name;
        $this->email = $email;
    }
 
    public function __invoke()
    {
        echo 'Объект Student вызывается в качестве функции';
    }
}
 
$objStudent = new Student('John', '[email protected]');
$objStudent();
?>

Как можно увидеть в этом примере, код вызывает объект $objStudent, как функцию. Поскольку мы используем метод __invoke(), это действие не приведет к ошибке. В этом и заключается назначение метода __invoke() – он позволяет нам вызывать объекты так же, как функции. 

Метод __clone()

Для создания копии существующего объекта можно использовать команду clone. Однако если нужно изменить свойства скопированного объекта после клонирования, следует определить в классе магический метод __clone(): 

<?php
Class Student_School {
}
 
class Student {
    private $name;
    private $email;
    private $object_student_school;
 
    public function __construct()
    {
        $this->object_student_school = new Student_School();
    }
 
    public function __clone()
    {
        $this->object_student_school = clone $this->object_student_school;
    }
}
 
$objStudentOne = new Student();
$objStudentTwo = clone $objStudentOne;
?>

Приведенный выше фрагмент кода на первом этапе создает поверхностную копию объекта – как следствие, вложенные объекты при этом не копируются. В контексте данного примера, если бы мы не использовали метод __clone(), копия объекта,  $objStudentTwo, по-прежнему указывала бы на объект Student_School, на который ссылается оригинал, $objStudentOne. Однако использование магического метода __clone()обеспечивает нам копирование Student_School вместе с главным объектом. 

Метод __debugInfo()

Этот магический метод вызывается при попытке сброса объекта с помощью функции var_dump(). Если вы не определили __debugInfo() в своем классе, он выведет все общедоступные, частные и защищенные свойства. Поэтому, если вы хотите ограничить информацию, отображаемую при сбросе, используйте этот метод. 

<?php
class Student {
    public $name;
    private $email;
    private $ssn;
 
    public function __debugInfo() 
    {
        return array('student_name' => $this->name);
    }
}
 
$objStudent = new Student();
var_dump($objStudent);
// object(Student)#1 (1) { ["student_name"]=> NULL } 
?>

Данный метод возвращает массив, состоящий из ключей и значений, которые будут отображаться в то время, когда функция var_dump() вызывается для объекта. Как вы можете видеть, у нас есть возможность полностью контролировать отображение данных, которые выводятся на экран в ходе сброса с помощью var_dump(). 

Метод __set_state()

Это статический метод, который используется в связке с функцией var_export(). Данная функция выводит структурированную информацию о переменной. Если вы используете функцию var_export() для экспорта класса, вам необходимо определить в нем метод __set_state(): 

<?php
class Student {
    public $name;
    private $email;   
 
    public function __construct($name, $email) 
    {
        $this->name = $name;
        $this->email = $email;
    }
 
    public static function __set_state(array $array) 
    {
        $obj = new Student;
        $obj->name = $array['name'];
        $obj->email = $array['email'];
 
        return $obj;
    }
}
 
$objStudent = new Student('John','[email protected]');
var_export($objStudent);
// Output: Student::__set_state(array( 'name' => 'John', 'email' => '[email protected]', ))
?>

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

Заключение

В этой статье мы рассмотрели все магические методы, доступные в PHP. Использование каждого метода было проиллюстрировано примером кода. Надеюсь, что эта статья пригодится вам в качестве референса или подсказки во время работы над разнообразными PHP-проектами.

Новый комментарий
нажимая кнопку, вы соглашаетесь с пользовательским соглашением
FAQ
Ответы на часто
задаваемые вопросы

Обновление модулей происходит в случаях:

  • Найдена критическая ошибка в работе.
  • Было собрано от клиентов достаточно пожеланий для новой версии.
  • Версия модуля не совместима с последней версией CMS.
Нет, это нарушение условий покупки
Да, изменение домена в дальнейшем допускается. Не разрешается только одновременная работа модуля на числе доменов, превышающем лимит лицензии. Если например, лицензия на один домен, то установка и работа на двух и более доменах считается нарушением. Также в целях отладки разрешается временная работа на тестовом сайте, если к нему нет доступа из интернета, например на локальном сервере.
По бесплатным модулям техподдержка не оказывается.
К сожалению, возврат в любом случае невозможен, это цифровой товар, а не обычный товар из обычного магазина. Покупая любой товар на сайте вы соглашаетесь с соответствующим пунктом из Лицензионного соглашения, поэтому тщательно ознакомьтесь с описанием модуля или плагина перед покупкой