Автоматическая загрузка классов

Большинство разработчиков объектно-ориентированных приложений используют такое соглашение именования файлов, в котором каждый класс хранится в отдельно созданном для него файле. Одна из самых больших неприятностей - необходимость писать в начале каждого скрипта длинный список подгружаемых файлов (по одному для каждого класса).

В PHP 5 это делать необязательно. Функция spl_autoload_register() позволяет зарегистрировать необходимое количество автозагрузчиков для автоматической загрузки классов и интерфейсов, если они в настоящее время не определены. Регистрируя автозагрузчики, PHP получает последний шанс для интерпретатора загрузить класс прежде, чем он закончит выполнение скрипта с ошибкой.

Подсказка

В то время как функция __autoload() также может быть использована для автоматической загрузки классов и интерфейсов, следует отдать предпочтение spl_autoload_register(), потому, что она предоставляет гораздо более гибкую альтернативу, позволяя регистрировать необходимое количество автозагрузчиков, например, для сторонних библиотек. По этой причине использование __autoload() не рекомендуется, а c PHP 7.2.0 объявлено устаревшим.

Замечание:

До версии PHP 5.3 исключения, выброшенные в функции __autoload(), не могли быть пойманы в блоке catch и приводили к фатальной ошибке. Начиная с версии 5.3 стало возможным их перехватывать, но при условии, если класс исключения будет доступен. Функция __autoload() также может использоваться рекурсивно для автоматической загрузки пользовательских классов исключений.

Замечание:

Автоматическая загрузка недоступна при использовании PHP в интерактивном режиме командной строки.

Замечание:

Если имя класса используется, например, для вызова через call_user_func(), то оно может содержать некоторые опасные символы, такие как ../. Поэтому рекомендуется не использовать данные от пользователей в таких функциях или же, по крайней мере, проверять значения в __autoload().

Пример #1 Пример автоматической загрузки

В этом примере функция пытается загрузить классы MyClass1 и MyClass2 из файлов MyClass1.php и MyClass2.php соответственно.

<?php
spl_autoload_register
(function ($class_name) {
    include 
$class_name '.php';
});

$obj  = new MyClass1();
$obj2 = new MyClass2(); 
?>

Пример #2 Еще один пример автоматической загрузки

В этом примере представлена попытка загрузки интерфейса ITest.

<?php

spl_autoload_register
(function ($name) {
    
var_dump($name);
});

class 
Foo implements ITest {
}

/*
string(5) "ITest"

Fatal error: Interface 'ITest' not found in ...
*/
?>

Пример #3 Автоматическая загрузка с перехватом исключения с версии 5.3.0+

В данном примере вызывается исключение и отлавливается блоком try/catch.

<?php
spl_autoload_register
(function ($name) {
    echo 
"Хочу загрузить $name.\n";
    throw new 
Exception("Невозможно загрузить $name.");
});

try {
    
$obj = new NonLoadableClass();
} catch (
Exception $e) {
    echo 
$e->getMessage(), "\n";
}
?>

Результат выполнения данного примера:

Хочу загрузить NonLoadableClass.
Невозможно загрузить NonLoadableClass.

Пример #4 Автоматическая загрузка с перехватом исключения в версиях 5.3.0+ - Класс пользовательского исключения отсутствует

В данном примере вызывается незагруженное пользовательское исключение.

<?php
spl_autoload_register
(function ($name) {
    echo 
"Хочу загрузить $name.\n";
    throw new 
MissingException("Невозможно загрузить $name.");
});

try {
    
$obj = new NonLoadableClass();
} catch (
Exception $e) {
    echo 
$e->getMessage(), "\n";
}
?>

Результат выполнения данного примера:

Хочу загрузить NonLoadableClass.
Хочу загрузить MissingException.

Fatal error: Class 'MissingException' not found in testMissingException.php on line 4