Конструктори та деструктори

Конструктор

__construct(mixed ...$values = ""): void

PHP дозволяє розробникам оголошувати для класів методи-конструктори. Метод-конструктор буде викликаний на кожному новоствореному екземплярі класу. Тому оголошення методу-конструктора зручне для ініціалізації того, що може знадобитися об'єкту на початку роботи.

Зауваження: Конструктори, які визначені у класах-батьках, не викликаються автоматично, якщо дочірній клас визначає свій конструктор. Щоб запустити конструктор батьківського класу, необхідно викликати його всередині конструктора дочірнього класу. parent::__construct(). Якщо в дочірньому класі не визначено конструктора, він буде успадкований від батьківського класу як звичайний метод (якщо батьківський конструктор не був визначений як приватний).

Приклад #1 Конструктори при наслідуванні

Loading...

В отличие от других методов, метод__construct() звільняється від звичайних правил сумісності сигнатурипри наследовании.

Конструктори - це звичайні методи, що викликаються при інстанціюванні об'єктів, що їх містять, або об'єктів дочірніх класів без конструктора. Тому в них може бути визначена довільна кількість аргументів, які можна оголосити обов'язковими, типізованими, за умовчанням. Аргументи конструктора вказуються у круглих дужках після імені класу.

Приклад #2 Оголошення аргументів у конструкторах

Loading...

Якщо клас не має конструктора, або його конструктор не містить обов'язкових параметрів, дужки після імені класу можна не писати.

Конструктори у старому стилі

До PHP 8.0.0 класи у глобальному просторі імен інтерпретуватимуть названий ім'ям класу метод як конструктор старого стилю. Цей синтаксис застарів і викликатиме помилку рівня **E_DEPRECATED**Але все одно ці методи будуть викликатися як конструктор. Якщо в класі є і метод __construct(), і метод з ім'ям класу, то як конструктор буде викликаний метод __construct()

Починаючи з PHP 8.0.0 для класів усередині простору імен та для всіх класів метод, названий на ім'я класу, буде проігнорований.

В новом коде всегда используют метод__construct()

Визначення властивостей об'єкта у конструкторі

Починаючи з PHP 8.0.0, через параметри конструктора можна встановлювати властивості об'єкта. Це поширена практика — надавати властивостям об'єкта значення лише рахунок переданих конструктор параметрів. Визначення властивостей класу в конструкторі значно скорочує кількість шаблонного коду такого випадку. Приклад вище можна буде переписати як показано нижче:

Приклад #3 Використання визначення властивостей конструктора

Loading...

Якщо декларація аргументу конструктора включає модифікатор, PHP інтерпретує його одночасно як аргумент конструктора, як властивість об'єкта, і автоматично встановить властивості значення, передане конструктор. При цьому, якщо не потрібно додаткової логіки, тіло конструктора можна залишити порожнім. Код конструктора виконається після того, як значення аргументів буде надано параметрам функції або властивостям класу.

Не всі передані в конструктор аргументи повинні бути просунутими (що встановлюють якості об'єкта). Просунуті та звичайні аргументи можна вказувати та зіставляти у будь-якому порядку. Просунуті аргументи не впливають на код, який виконується в конструкторі.

Зауваження :

Вказати модифікатор області видимості public protectedилиprivate) — це найімовірніший спосіб застосувати просунуту установку властивостей, але будь-який інший модифікатор (наприклад, readonly) дасть такий самий ефект.

Зауваження :

Не можна вказувати властивості об'єкта тип callable. Це з неоднозначністю, що вони представляють для движка PHP. Тому і аргументів конструктора, які встановлюють класу якості, також не можна вказувати тип callable. Будь-які інші декларації типів допустимі.

Зауваження :

Оскільки при розборі коду PHP трансформує синтаксичний цукор просунутих властивостей у звичайне декларування властивостей конструктора з тими ж модифікаторами видимості та типом даних, які вказані у просунутому аргументі, а також надає значення просунутого аргументу і параметру функції, і властивості класу, все без винятку обмеження на визначення аргументів конструктора буде застосовано як до параметрів функції, і до властивостей класу.

Зауваження :

Атрибути , встановлені аргументу в просунутому конструкторі, будуть репліковані як у аргумент, і на властивість класу. Значення за умовчанням для аргументу в просунутому конструкторі поширюється лише аргумент, а чи не властивість.

New в ініціалізації класу

З PHP 8.1.0 об'єкти можна надавати як значення параметрів за умовчанням, статичних змінних і глобальних констант, а також в аргументах атрибутів. Об'єкти також можна передавати у функцію define()

Зауваження :

При цьому динамічні чи нестрокові імена класів чи анонімних класів не дозволені. Використовувати розпакування аргументів заборонено. Непідтримувані вирази як аргументи не дозволені.

Приклад #4 Приклад використання new в ініціалізації класу

Loading...

Статичні методи створення об'єкту

PHP підтримує лише один конструктор для класу. Однак буває так, що потрібно створювати різні об'єкти для вхідних даних. Рекомендований спосіб використовувати статичні методи як обгортки над конструктором.

Приклад #5 Використання статичних методів створення об'єктів

Loading...

Конструктор можна зробити закритим або захищеним для запобігання прямому виклику. Тоді об'єкт класу можна буде створити лише виклик статичного методу. Оскільки це методи того ж класу, вони мають доступ до всіх його прихованих методів, навіть якщо вони відносяться до різних екземплярів класу. Закритий конструктор опціональний, і може бути оголошений або не мати сенсу в різних ситуаціях.

У прикладі вище три публічні статичні методи показують різні способи створення екземпляра об'єкта.

  • МетодfromBasicData()приймає явні параметри, створює екземпляр класу через конструктор та повертає об'єкт.
  • МетодfromJson()приймає JSON-рядок, здійснює над нею перетворення, витягує необхідні для створення об'єкта дані і, так само як і попередній метод, викликає конструктор і повертає створений об'єкт.
  • МетодfromXml()приймає XML-рядок, витягує необхідні дані і, оскільки в конструкторі немає обов'язкових параметрів, викликає його без них. Після цього, оскільки йому доступні приховані властивості, він надає їм значення безпосередньо. Після цього повертає готовий об'єкт.

У всіх трьох випадках ключове слово static транслюється в ім'я класу, в якому код викликається. У нашому випадку — до класу Product

Деструктори

__destruct(): void

PHP успадковує концепцію деструктора, аналогічну до інших об'єктно-орієнтованих мов, наприклад, C++. Деструктор буде викликаний у разі звільнення всіх посилань на об'єкт або при завершенні скрипту (порядок виконання деструкторів не гарантується).

Приклад #6 Приклад використання деструктора

Loading...

Як і конструктори, деструктори, оголошені у батьківському класі, не викликатимуться автоматично. Щоб запустити деструктор батьківського класу, необхідно викликати parent::__destruct() у тілі деструктора дочірнього класу. Аналогічно конструкторам, дочірній клас, у якому не визначено деструктора, успадковує його з батьківського класу.

Деструктор буде викликаний навіть якщо скрипт був зупинений функцією exit(). Виклик функції exit() у деструкторі запобігає запуску всіх інших процедур завершення роботи.

Зауваження :

Деструктори, що викликаються при завершенні скрипта, викликаються після надсилання заголовків HTTP. На етапі завершення роботи скрипта робоча директорія SAPI (наприклад, Apache) може змінитися.

Зауваження :

Спроба викинути виняток із деструктора (викликаного під час завершення роботи скрипта) спричинить фатальну помилку.