Автоматичний завантажувач класів
lang_of_article_differ
want_proper_trans
Підключення інших файлів в вашому сценарії
Коли ви пишете програму, яка складається з більш ніж одного файлу вам необхідно включити (include
або require
) файли за допомогою
include 'filename.php';
require 'another.php';
Якщо ви використовуєте купу класів в вашому додатку вам потрібно щоб всі вони були проінклюжені в файл в якому ви їх використовуєте, це логічно. Коли класів багато, потрібно писати купу непотрібного коду вгорі сценарію який спотворює (це корректно, але не етично можна сказати) вашого коду
Ще одним мінусом явного включення файлу в ваш сценарій є те, що інтерпретатору мови прийдеться обробити включені файли і витратити на це час, навіть якщо насправді ви не використали класи які знаходяться в тих файлах
<?php
include_once 'some/library.php'; // SomeLibrary class
if ($userLogged) {
$lib = new SomeLibrary();
// do some stuff
} else {
redirect_to('/');
}
У цьому сценарії файл some/library.php
буде завжди аналізуватися PHP і зїдати оперативну пам'ять і процесорний час, навіть якщо користувач не увійшов в систему і перенаправляється на головну сторінку сайту.
Таким чином, використання явного включення файлів не завжди є оптимальним рішенням. Звичайно, ви можете включити вашу бібліотеку тільки в тому випадку якщо користувач залоглен на сайті, проте це знову ж таки потворить ваш код:
<?php
if ($userLogged) {
include_once 'some/library.php'; // SomeLibrary class
$lib = new SomeLibrary();
// do some stuff
} else {
redirect_to('/');
}
Автоматичне завантаження відсутніх файлів
Ручне завантаження залежних файлів це добре, звичайно, але це не завжди виглядає елегантно, погодьтесь. Насправді, php
має здатність включати файли автоматично: є магічна функція яка викликається коли клас, який використовується в скрипті не був знайдений в поточній області видимості. Це робиться за допомогою spl_autoload_register
:
spl_autoload_register(function ($class) {
// this function would be called when php would not find some $class
});
Ви можете встановити функцію автозавантаження на початку вашої програми і забути про включення файлів після цього моменту. Spl_autoload_register
приймає один параметр - функцію, яка повинна викликатися, коли якийсь клас не знайдений. Її параметр $ class
матиме значення ім'я класу (включаючи простір імен) який не був знайдений:
"\Catchmetech\AutoloadingLesson\ExampleController"
Якщо ви будете правильно генерувати імена для класів в системі і розміщувати їх в потрібних папках, то автозавантаження вам здорово допоможе в подальшому.
Кращі практики ( PSR
) говорять, що простір імен повинен відповідати шляху в файловій системі і кожен клас повинен бути в окремому файлі. Так, клас в наведеному вище прикладі повинен знаходитися в папці Catchmetech\AutoloadingLesson
і повинен мати імя ExampleController.php
. Звичайно, кожен клас повинен використовувати простір імен, як я вже згадував в попередніх уроках :)
Отже, як визначити, який файл я повинен включити в моїй функції автозавантаження? За допомогою str_replace
замінимо в nemaspace роздільники в $class
з правильним для нашої операційної системиDIRECTORY_SEPARATOR
, додамо розширення файлу і вуаля:
$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
Добре, у нас є шлях до файлу, але він відносний, так як ми використовували неймспейс класу для цього діла. Ми повинні додати до цього шляху префікс $baseDir
який повинен відповідати абсолютному шляху до каталогу, де лежить наш додаток. Якщо ви правильно назвали класи і файли - все повинно працювати
$baseDir = __DIR__.'/';
$fileName = $baseDir.$fileName;
Крім того, ми можемо перевірити, чи дійсно існує файл який ми шукаємо в файловій системі. Це можна зробити за допомогою is_file
. У випадку якщо файл не існує - викидається exception:
spl_autoload_register(function ($class) {
$base_dir = __DIR__.'/';
$file = $base_dir . str_replace('\\',DIRECTORY_SEPARATOR, $class) . '.php';
if (file_exists($file)) {
require $file;
} else {
throw new \Exception ('can\'t include '.$file.PHP_EOL.' when trying to load `'.$class.'`');
}
});
Ось і все, ми зробили автоматичний завантажувач класів! Розмістіть код що вище, попередньо підлаштувавши його під себе, в верхній частині завантажувального файлу вашої програми і забудьте про купи include
в файлах!