
Конечно, если вы используете Composer для установки различных php библиотек, фреймворков и расширений, грех не воспользоваться его автозагрузчиком, про который я писал тут. Но предположим что Composer вы, по каким-то причинам, не можете использовать.
Файл автозагрузчика классов (autoload.php) подключается в точке входа (файл index.php). Сам класс автозагрузчика регистрируется в начале запуска приложения после выполнения метода run() с помощью функции spl_autoload_register(), которая вызывает метод autoload() класса ClassLoader. Автозагрузчик классов вызывается автоматически каждый раз при вызове любого класса, который не был объявлен.
Для работы автозагрузчика, каждый подключаемый класс должен быть в отдельном php-файле, который называться должен аналогично названию класса. Например класс Config должен находиться в файле Config.php
Автозагрузчик прежде всего ищет запрашиваемый класс в карте классов, которая представляет собой ассоциативный массив, находящийся в отдельном файле vendor/classes.php. Он содержит названия классов в виде свойств массива и путь к файлам данных классов в виде значений. Например:
'Config' => 'library/Config.php'.
В карту сайта следует включить служебные классы, которые нужны для работы приложения. Карта классов используется для ускорения загрузки.
Не найдя класс в карте классов, вызывается дополнительный метод, который ищет файл класса в массиве дирректорий public static $dir. В данный массив следует включить названия основных папок, которые предназначены для создания в них файлов классов по ходу работы над созданием сайта.
При использовании концепции MVC, это прежде всего controller и model.
После использования обоих попыток подключить требуемый класс, проверяется объявлен ли он. И если нет – генерируется исключение с выводом соответствующего сообщения.
Структура каталогов/файлов:
- config - db.php - vendor - autoload.php - classes.php - main.php<span class="redactor-invisible-space"></span> - controller - MyController.php - model - view - index.php
Рассмотрим код основных файлов.
index.php:
<?php define("ROOT_DIR",dirname(__FILE__).'/'); require_once "vendor/autoload.php"; //автозагрузчик классов require_once "vendor/main.php"; //основной класс приложения $application = new Application(); $application->run();В данном файле (точке входа) первым делом, создаем константу ROOT_DIR, которая будет использоваться для указания пути к корню приложения.
Далее загружаем файлы с классами, создаем объект приложения и вызываем метод, который вызывает и подключает все нужные для работы классы/методы, а прежде всего автозагрузчик классов.
vendor\autoload.php
<?php class ClassLoader { public static $classMap; public static $addMap = array(); public static $dir = [ 'controller', 'model', ]; //Добавить класс к карте классов public static function addClassMap($class = array()){ self::$addMap = array_merge(self::$addMap, $class); } public static function autoload($className){ //подключаем и сохраняем карту классов. Добавляем пользовательские классы. self::$classMap = array_merge(require(__DIR__ . '/classes.php'), self::$addMap); //Ищем в карте классов if (isset(self::$classMap[$className])) { $filename = self::$classMap[$className]; include_once ROOT_DIR . $filename; //Ищем в папках } else { self::library($className); } //Проверка был ли объявлен класс if (!class_exists($className, false) && !interface_exists($className, false) && !trait_exists($className, false)) { throw new Exception('Невозможно найти класс '.$className); } } public static function library($className){ foreach (self::$dir as $d){ $filename = ROOT_DIR . $d . '/'. $className . ".php"; if (is_readable($filename)) { require_once $filename; } } } }Это класс самого автозагрузчика, который ищет файл требуемого класса сначала в карте классов, а не найдя в списке директорий, указанных в свойстве $dir. Так же класс генерирует исключение в случае, если затребованный класс подключить не удалось.
Сама карта классов должна быть в таком формате (файл vendor\classes.php):
<?php return [ 'ConfigDb' => 'config/db.php', 'my\widgets\Menu' => 'widgets/Menu.php', //можно использовать пространства имен 'my\helpers\Html' => 'helpers/Html.php', ];
vendor\main.php
<?php class Application { public function run(){ $this->Loader(); //... } public function Loader(){ spl_autoload_register(['ClassLoader', 'autoload'], true, true); try{ $config = new ConfigDb(); echo $config->get('database', 'login'); //mylogin echo MyController::$params; //KSL //Пример добавления каталога в автозагрузчик классов //ClassLoader::$dir[] = 'view'; //Пример добавления класса MyClass к карте классов //ClassLoader::$addMap['MyClass'] = 'folder/MyClass.php'; } catch (Exception $e){ echo '<h2>Внимание! Обнаружена ошибка.</h2>'. '<h4>'.$e->getMessage().'</h4>'. '<pre>'.$e->getTraceAsString().'</pre>'; exit; } } }Это основной класс приложения. В данном случае при его запуске из index.php, метод run() первым делом вызывает метод Loader(), который регистрирует наш автозагрузчик классов с помощью функции spl_autoload_register(), в которой указывается класс и метод самого автозагрузчика. В этот метод, данная функция, передает название вызываемого класса (или класса, экземпляр которого мы пытаемся создать).
Для примера, тут создается объект класса ConfigDb с вызовом его метода get(), возвращающего некоторые данные. Данный класс у нас прописан в карте классов и таким образом проверяем работу автозагрузчика по поиску в карте классов.
После этого, проверяем автозагрузчик на предмет поиска в списке указанных для этого директорий. Для этого вызываем статическое свойство $params класса MyController. Данный класс размещен в папке controller, которая включена в массив свойства $dir, а значит класс подключится на втором этапе поиска с выводом значения запрашиваемого свойства.
Чтобы была возможность протестировать и не набирать все вручную - выкладываю архив файлов. Можно запустить на локальном сервере. При этом на экране будет выведен результат вызова двух методов, которые использованы для проверки автозагрузчика классов.