Все про автозавантаження в php

PHP-програмісту, котрі використовують ООП, досить часто потрібно так організувати класи, щоб визначення кожного з них знаходилося в окремому файлі. В такому випадку програміст нерідко стикається з досить нудною завданням: підключенням використовуваних класів, які використовуються в проекті. Щоб автоматизувати даний процес, в PHP 5.0 була передбачена можливість автозавантаження класів.

Починаючи з версії PHP 5.0 була введена функція __autoload (). Спосіб роботи її зовсім простий: коли скрипт в коді натикається на невідомий йому клас, він викликає функцію __autoload (). за умови, що вона була визначена, і передає їй назву невідомого класу в надії, що ця функція підключить файл з визначенням даного класу. Таким чином, в функції __autoload () слід вказати яким саме способом буде відбуватися пошук необхідних до підключення класів.

Припустимо, у нас є кілька класів проекту в папці classes. Їх назви та змісту такі:

У головному скрипті нам потрібно організувати їх автоматичне завантаження. Для цього в головному скрипті ми оголошуємо функцію автозавантаження яка шукає спільні класи в папці classes. Після чого можна використовувати ці класи:

В результаті на сторінці ми побачимо таку картину:

Як видно з прикладу, у нас оголошено кілька класів у окремих файлах, а в головному скрипті немає жодного виклику інструкцій include / require. Причому, автозавантаження класів відбувається в міру необхідності.

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

Використання автозавантаження з бібліотеки SPL

Починаючи з версії PHP 5.1.2 була впроваджена нова система автозавантаження класів, яка була включена в бібліотеку SPL (Standard PHP Library). Основна відмінність нової системи автозавантаження в тому, що можна визначати скільки завгодно функцій автозавантаження. Всі вони формують стек функцій автозавантаження, в якому кожна наступна додана функція автозавантаження потрапляє в кінець стека. Таким чином, при роботі скрипта, коли він натикається на невідомий йому клас, він по черзі викликає всі функції автозавантаження, що знаходяться в стеку до тих пір, поки не буде завантажений необхідний клас.

Так, нова система автозавантаження включає цілих 6 функцій управління автозавантаженням:

  • spl_autoload_call - примусово завантажує клас по його імені, використовуючи всі доступні в системі Автозавантажувач;
  • spl_autoload_extensions - повертає / модифікує розширення файлів, у тому числі відбувається завантаження неініціалізованих класів;
  • spl_autoload_functions - повертає список всіх зареєстрованих Автозавантажувач в системі;
  • spl_autoload_register - реєстрація власного Автозавантажувач в стеці автозавантаження;
  • spl_autoload_unregister - видалення Автозавантажувач з стека автозавантаження;
  • spl_autoload - основна функція автоматичного завантаження класів. Саме вона викликається при зверненні до класу, який ще не инициализирован. Ця функція активує всі автоматичні завантажувачі з стека в порядку їх додавання.

Щоб включити спосіб автозавантаження за замовчуванням, потрібно лише викликати функцію spl_autoload_register () без будь-яких параметрів. Після цього активізується засіб автозавантаження класів, яке автоматично викликає функцію spl_autoload () при спробі створити в програмі екземпляр невідомого класу. Як параметр цієї функції передається ім'я невідомого класу, яке згодом перетвориться в ім'я файлу. Механізм такий: ім'я класу наводиться до нижнього регістра, і до нього по черзі додаються всі стандартні розширення (спочатку .inc, потім .php), після чого проводиться пошук файлу в тій же директорії, де розташований скрипт, і знайшовши його, спробує завантажити вміст цього файлу, вважаючи, що в ньому знаходиться визначення невідомого класу. Також в реалізації автозавантаження класів за замовчуванням підтримуються простору імен, при цьому імені пакета ставиться у відповідність ім'я каталогу. І все-таки в автозавантаженні за замовчуванням занадто багато обмежень. Тому практично завжди розробники пишуть свої функції автозавантаження і додають їх в стек.

Припустимо, у нас є два різних (classes і lib) каталогу, в якому зберігаються деякі класи, і для автозавантаження класів з кожного каталогу ми хочемо зробити власну функцію автозавантаження (виключно як приклад).

В результаті на сторінці отримаємо:

executing __aturoload () with aClassName = MyClass1

executed MyClass1 :: __ construct () method

executing __aturoload () with aClassName = MyClass3

executed MyClass3 :: __ construct () method

Fatal error: Class 'MyClass2' not found in Z: \ home \ test.loc \ www \ index.php on line 44

З прикладу можна бачити, що в скрипті зареєстровані дві функції автозавантаження, які були по черзі викликані. Після чого з стека автозавантаження була видалена одна функція, і зроблено спробу її виклику, і, як наслідок - скрипт видав помилку.

Перехід з функції __autoload () на використання SPL-автозавантаження

В мови PHP функція __autoload () є застарілою, тому в майбутніх версіях PHP підтримка цієї функції не гарантується. З використанням даної функції в проекті пов'язана ще одна проблема - відключається можливість використання SPL-автозавантаження. Щоб не попастися в ситуацію, коли виявиться, що функція __autoload () не викликається PHP-інтерпретатором, або в разі необхідності підтримки SPL-автозавантаження, можна просто викликати функцію spl_autoload_register () з переданої в якості аргументу рядком "__autoload", як показано нижче:

Механізм автоматичного завантаження класів - це ще один украй затребуваний інструмент в арсеналі PHP-розробника. Використання цього механізму зустрічається повсюдно: будь то код будь-якого невеликого проекту або новомодний фреймворк.
Розуміння механізму автозавантаження класів в php дає значні переваги освоїв її розробнику. За великим рахунком завдання впровадження функцій автозавантаження - автоматизувати операцію повсюдного виклику інструкцій require / include. Звичайно, також знання цих нюансів дає більш глибоке пізнання про роботу PHP-скриптів, знайомство з php-фреймворками відбуватиметься полее м'яко і т.д.

Спільнота PHP-розробників давно займається стандартизацією того, як найкраще організувати механізм автозавантаження, який би використовувався всіма іншими зацікавленими сторонами. Переслідується досить банальна мета: щоб при підключенні стороннього класу або фреймворка можна було швидко його впровадити в вашу автозагрузку і почати використовувати як можна швидше. Поточна специфікація, що описує актуальний стандарт автозавантаження називається PSR-4. Її переклад доступний тут.