До версии PHP 5 обычной практикой было использование функций require, require_once, include, include_once для загрузки файлов, содержащих нужные классы.
Пример использования функций:
1 2 3 4 5 |
<?php requre_once 'lib/src/SomeClass.php'; $someObject = new SomeClass('Object'); |
Проблема такого подхода в том, что:
- Необходимо указывать каждый файл в котором содержится необходимый класс.
- Использование обращения к объекту не подгруженного класса вызывало ошибку.
- Плюс, указанные файлы подгружались всегда, независимо от их необходимости.
- Изменение структуры хранения файлов, влекло за собой переписывание многочисленных включений.
- Легко было запутаться в том, что необходимо включить в файл, а что включать не нужно.
Как итог, огромное количество включений ненужных файлов и ошибки в зависимостях из-за отсутствия включения нужных.
Новый подход в PHP 5
Новый механизм, предложенный в PHP5 изменил подход, предложив автозагрузку классов. За автозагрузку отвечала aункция __autoload() которая вызывалась каждый раз, когда создавался объект неизвестного класса.
Реализовав функцию автозагрузки классов мы получали простой механизм управления включением классов.
1 2 3 4 5 6 7 8 |
<?php function __autoload($class){ require_once "lib/src/SomeClass.php"; } $someObject = new SomeClass("Object"); |
Класс SomeClass ранее не был подключен и будет вызвана функция __autoload(), которой будет передано название класса как параметр $class.
В свою очередь, она попробует подключить файл содержащий данный класс.
Улучшенный автозагрузчик
Подход с автозагрузкой классов был настолько успешен, что уже в версии PHP 5.1.2 стала доступна новая функция: spl_autoload_regicter();
1 |
spl_autoload_registr (callable $autoload_function = ? , bool $throw = true, bool $prepend = false) : bool |
Список параметров
autoload_function
Имя функции, реализующей метод spl_autoload(). Если аргумент не задан, будет зарегистрирована реализация по умолчанию.
throw
Этот параметр определяет, должна ли spl_autoload_register() выбрасывать исключение, если зарегистрировать autoload_function
оказалось невозможным.
prepend
Если передано значение true, spl_autoload_register() поместит указанную функцию в начало очереди вместо добавления в конец.
Данная функция позволяет регистрировать любую переданную ей функцию как реализацию механизма автозагрузки классов. Если вызвать ее без параметров, то в качестве механизма автозагрузки классов будет выступать функция spl_autoload().
Стоит помнить, что функция spl_autoload_register() имеет свою очередь, поэтому можно регистрировать более одной функции. Функции обратного вызова будут вызываться в порядке их регистрации.
В версии PHP5.3 добавлена поддержка пространства имен (namespase).
Распространенный подходы автозагрузки классов
Регистрация автозагрузки классов вручную
Все просто, создаем автозагрузчик и регистрируем в нем все классы вручную.
1 |
<?php |
Имена классов как указатели пути к файлу
Этот подход использовался в шаблонизаторе Twig и Zend Fraemwork первой версии. Как ясно из заголовка, само имя класса указывает на папку, где находится файл, содержащий этот класс.
Простейший пример именования, через нижнее подчеркивание, которое в последствии обрабатывается функцией str_replace('_', '/', '$class')
.
Все просто, получаем имя класса Model_SomeClass и преобразуем его в путь «Model/SomeClass«.
1 |
<?php |
Автозагрузка классов использующих пространства имен (namespace)
На сегодняшний день это самый популярный подход и лучший способ применения самих пространств имен. Суть его в том, что мы регистрируем пространство имен: папку в файловой системе, а все вложенные файлы и папки будут подхватываться автоматически. В сочетании с автозагрузчиком классов этот подход позволил экономить не только ресурсы серверов, но и время программистов.
1 |
<?php |