Sobes.tech
Middle

Кои магически методи съществуват в PHP и как се използват?

sobes.tech AI

Отговор от AI

Магическите методи в PHP са специални методи, започващи с двойно подчертаване (например, __construct), които се извикват автоматично в определени ситуации.

Основните магически методи и тяхното използване:

  • __construct(): Извиква се при създаване на обект от класа. Използва се за инициализация на свойствата на обекта и изпълнение на начални действия.

    <?php
    class MyClass {
        public function __construct() {
            echo "Обект създаден!";
        }
    }
    $obj = new MyClass(); // Ще изведе "Обект създаден!"
    
  • __destruct(): Извиква се при унищожаване на обекта (например, когато скриптът приключи или обектът бъде изтрит). Използва се за освобождаване на ресурси (затваряне на файлове, връзки с бази данни).

    <?php
    class MyClass {
        public function __destruct() {
            echo "Обект унищожен!";
        }
    }
    $obj = new MyClass();
    unset($obj); // Ще изведе "Обект унищожен!"
    
  • __call(string $name, array $arguments): Извиква се при опит да се извика недостъпен или несъществуващ метод в контекста на обекта. $name съдържа името на метода, а $arguments - масив с аргументи.

    <?php
    class MyClass {
        public function __call($name, $arguments) {
            echo "Извикан недостъпен метод '{$name}' с аргументи: " . implode(', ', $arguments);
        }
    }
    $obj = new MyClass();
    $obj->nonExistentMethod('arg1', 'arg2'); // Ще изведе "Извикан недостъпен метод 'nonExistentMethod' с аргументи: arg1, arg2"
    
  • __callStatic(string $name, array $arguments): Извиква се при опит да се извика недостъпен или несъществуващ статичен метод в контекста на класа. Аналогичен е на __call, но за статични извиквания.

    <?php
    class MyClass {
        public static function __callStatic($name, $arguments) {
            echo "Извикан недостъпен статичен метод '{$name}' с аргументи: " . implode(', ', $arguments);
        }
    }
    MyClass::nonExistentStaticMethod('static_arg'); // Ще изведе "Извикан недостъпен статичен метод 'nonExistentStaticMethod' с аргументи: static_arg"
    
  • __get(string $name): Извиква се при опит да се получи стойност на недостъпен или несъществуващ свойство в контекста на обекта. $name съдържа името на свойството.

    <?php
    class MyClass {
        private $data = ['key' => 'value'];
        public function __get($name) {
            if (array_key_exists($name, $this->data)) {
                return $this->data[$name];
            }
            return null;
        }
    }
    $obj = new MyClass();
    echo $obj->key; // Ще изведе "value"
    echo $obj->nonExistentKey; // Ще изведе празен низ (в зависимост от връщаната стойност null)
    
  • __set(string $name, mixed $value): Извиква се при опит да се зададе стойност на недостъпен или несъществуващ свойство в контекста на обекта. $name съдържа името на свойството, а $value - задаваната стойност.

    <?php
    class MyClass {
        private $data = [];
        public function __set($name, $value) {
            $this->data[$name] = $value;
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    $obj->newKey = 'newValue';
    print_r($obj->getData()); // Ще изведе Array ( [newKey] => newValue )
    
  • __isset(string $name): Извиква се при извикване на isset() или empty() върху недостъпен или несъществуващ свойство в контекста на обекта. Връща булево стойност.

    <?php
    class MyClass {
        private $data = ['present' => 'value'];
        public function __isset($name) {
            return array_key_exists($name, $this->data);
        }
    }
    $obj = new MyClass();
    var_dump(isset($obj->present));     // Ще изведе bool(true)
    var_dump(isset($obj->absent));      // Ще изведе bool(false)
    
  • __unset(string $name): Извиква се при извикване на unset() върху недостъпен или несъществуващ свойство в контекста на обекта.

    <?php
    class MyClass {
        private $data = ['remove_me' => 'value_to_remove'];
        public function __unset($name) {
            if (array_key_exists($name, $this->data)) {
                unset($this->data[$name]);
                echo "Свойството '{$name}' е изтрито.\n";
            }
        }
        public function getData() {
            return $this->data;
        }
    }
    $obj = new MyClass();
    print_r($obj->getData());
    unset($obj->remove_me); // Ще изведе "Свойството 'remove_me' е изтрито." и ще изтрие елемента от $data
    print_r($obj->getData());
    
  • __sleep(): Извиква се преди сериализация на обекта с използване на serialize(). Трябва да върне масив с имената на свойствата, които трябва да бъдат сериализирани.

    <?php
    class MyClass {
        public $prop1 = 'value1';
        public $prop2 = 'value2';
        public function __sleep() {
            return ['prop1']; // Сериализираме само prop1
        }
    }
    $obj = new MyClass();
    $serialized = serialize($obj); // Сериализира само prop1
    echo $serialized; // Ще изведе примерно O:7:"MyClass":1:{s:5:"prop1";s:6:"value1";}
    
  • __wakeup(): Извиква се след десериализация на обекта с използване на unserialize(). Използва се за възстановяване на връзки с бази данни или други действия, необходими след възстановяване на обекта.

    <?php
    class MyClass {
        public $prop1;
        public $resource; // Предположим, че това е ресурс за връзка
        public function __wakeup() {
            // Възстановяване на ресурса, например връзка с база данни
            $this->resource = fopen('/tmp/my_file.txt', 'w'); // Пример
            echo "Обект събуден и ресурс възстановен!\n";
        }
        public function __sleep() {
            // В __sleep не сериализираме ресурса
            return ['prop1'];
        }
        public function __destruct() {
            if (is_resource($this->resource)) {
                fclose($this->resource);
                echo "Ресурсът е затворен.\n";
            }
        }
    }
    $obj = new MyClass();
    $obj->prop1 = 'deserialized value';
    $serialized = serialize($obj);
    unset($obj);
    
    $deserialized_obj = unserialize($serialized); // Ще извика __wakeup()
    var_dump($deserialized_obj->prop1);
    
  • __toString(): Извиква се, когато обектът се използва като низ (например, при echo или конкатенация). Трябва да върне низово представяне на обекта.

    <?php
    class MyClass {
        public $name = "MyObject";
        public function __toString() {
            return "Обект от тип MyClass с име: " . $this->name;
        }
    }
    $obj = new MyClass();
    echo $obj; // Ще изведе "Обект от тип MyClass с име: MyObject"
    
  • __invoke(...): Извиква се при опит да се извика обект като функция. Може да приема произволен брой аргументи.

    <?php
    class MyCallableClass {
        public function __invoke(...$args) {
            echo "Обектът беше извикан като функция с аргументи: " . implode(', ', $args);
        }
    }
    $obj = new MyCallableClass();
    $obj('arg1', 123); // Ще изведе "Обектът беше извикан като функция с аргументи: arg1, 123"
    
  • __set_state(array $properties): Извиква се статично за класове, експортирани с помощта на var_export(). Получава масив с експортираните свойства. Трябва да създаде нов обект на класа и да го върне.

    <?php
    class MyClass {
        public $prop;
        public static function __set_state(array $properties) {
            $obj = new MyClass();
            $obj->prop = $properties['prop'];
            return $obj;
        }
    }
    $obj = new MyClass();
    $obj->prop = 'exported value';
    $exported = var_export($obj, true); // Експортира обекта
    // $exported ще съдържа код за създаване на обекта, използващ __set_state()
    eval('$restored_obj = ' . $exported . ';');
    var_dump($restored_obj); // Ще изведе обект MyClass с пропърти 'exported value'
    
  • __debugInfo(): Извиква се при извикване на функции като var_dump() за обекта. Методът трябва да връща масив с информация за свойствата на обекта, които трябва да бъдат показани.

    <?php
    class MyClass {
        public $publicProp = 'public';
        private $privateProp = 'private';
        public function __debugInfo() {
            return ['publicProp' => $this->publicProp, 'private_info' => 'някои детайли за privateProp'];
        }
    }
    $obj = new MyClass();
    var_dump($obj); // Ще изведе информацията, върната от __debugInfo()
    
  • __clone(): Извиква се след операцията по клониране (clone) на обекта. Използва се за дълбоко копиране на вътрешни обекти или структури от данни.

    <?php
    class SubObject {
        public $value;
        public function __construct($value) {
            $this->value = $value;
        }
    }
    class MyClass {
        public $object;
        public $anotherProp;
        public function __construct() {
            $this->object = new SubObject('initial');
            $this->anotherProp = 'original';
        }
        public function __clone() {
            // Клонираме вложения обект за дълбоко копиране
            $this->object = clone $this->object;
        }
    }
    $obj = new MyClass();
    $cloned_obj = clone $obj;
    
    // Сега $obj->object и $cloned_obj->object са различни екземпляри на SubObject
    $cloned_obj->object->value = 'modified';
    
    var_dump($obj->object->value);       // Ще изведе "initial"
    var_dump($cloned_obj->object->value); // Ще изведе "modified"
    

Таблица с кратко описание:

Метод Описание Извиква се при...
__construct() Конструктор на класа. Създаване на нов екземпляр на класа.
__destruct() Деструктор на класа. Изтриване на обекта или приключване на скрипта.
__call() Обработка на извикване на несъществуващи/недостъпни методи. Опит за извикване на недостъпен или несъществуващ метод на обекта.
__callStatic() Обработка на извикване на несъществуващи/недостъпни статични методи. Опит за извикване на недостъпен или несъществуващ статичен метод на класа.
__get() Обработка на получаване на стойност на недостъпно/несъществуващо свойство. Опит за получаване на стойност на недостъпно или несъществуващо свойство.
__set() Обработка на задаване на стойност на недостъпно/несъществуващо свойство. Опит за задаване на стойност на недостъпно или несъществуващо свойство.
__isset() Обработка на isset() или empty() за свойства. Вика се при isset() или empty() върху недостъпно или несъществуващо свойство.
__unset() Обработка на unset() за свойства. Вика се при unset() върху недостъпно или несъществуващо свойство.
__sleep() Подготовка за сериализация. Вика се при serialize() на обекта.
__wakeup() Постобработка след десериализация. Вика се при unserialize() на обекта.
__toString() Строго низово представяне на обекта. Използване на обекта като низ (например, при echo).
__invoke() Обект като функция. Опит за извикване на обекта като функция.
__set_state() Създаване на обект след експортиране с var_export(). Оценка на код, генериран от var_export().
__debugInfo() Информация за отстраняване на грешки (var_dump()). Вика се при var_dump() на обекта.
__clone() Постклониране. Вика се при clone на обекта.