Nette RobotLoader
RobotLoader — это инструмент, который обеспечит вам комфорт автоматической загрузки классов для всего вашего приложения, включая сторонние библиотеки.
- избавимся от всех
require - будут загружаться только необходимые скрипты
- не требует строгих соглашений по именованию каталогов или файлов
- чрезвычайно быстрый
- никакой ручной актуализации кеша, все происходит автоматически
- зрелая, стабильная и широко используемая библиотека
Таким образом, мы можем забыть об этих известных блоках кода:
require_once 'Utils/Page.php'; require_once 'Utils/Style.php'; require_once 'Utils/Paginator.php'; // ... Установка
RobotLoader можно скачать как один отдельный файл RobotLoader.php, который вы включите с помощью require в свой скрипт, и сразу же получите удобную автозагрузку для всего приложения.
require '/path/to/RobotLoader.php'; $loader = new Nette\Loaders\RobotLoader; // ... Если вы создаете приложение, использующее Composer, вы можете установить его с помощью него:
composer require nette/robot-loader Использование
Подобно тому, как робот Google обходит и индексирует веб-страницы, так и RobotLoader обходит все PHP-скрипты и записывает, какие классы, интерфейсы, трейты и перечисления он в них нашел. Результаты сканирования он затем сохраняет в кеш и использует при следующем запросе. Достаточно лишь указать, какие каталоги он должен обходить и куда сохранять кеш:
$loader = new Nette\Loaders\RobotLoader; // каталоги, которые RobotLoader должен индексировать (включая подкаталоги) $loader->addDirectory(__DIR__ . '/app'); $loader->addDirectory(__DIR__ . '/libs'); // установим кеширование в каталог 'temp' $loader->setTempDirectory(__DIR__ . '/temp'); $loader->register(); // запустим RobotLoader И это все, с этого момента нам не нужно использовать require. Отлично!
Если RobotLoader при индексации столкнется с дублирующимся именем класса, он выбросит исключение и сообщит вам об этом. RobotLoader также автоматически обновляет кеш, когда ему нужно загрузить класс, который он не знает. Это рекомендуется отключать на production-серверах, см. Кеширование.
Если вы хотите, чтобы RobotLoader пропустил какие-то каталоги, используйте $loader->excludeDirectory('temp') (можно вызывать многократно или передать несколько каталогов).
По умолчанию RobotLoader сообщает об ошибках в PHP-файлах, выбрасывая исключение ParseError. Это можно подавить с помощью $loader->reportParseErrors(false).
Приложение Nette
Внутри приложения Nette, где в загрузочном файле Bootstrap.php используется объект $configurator, запись можно упростить:
$configurator = new Nette\Bootstrap\Configurator; // ... $configurator->setTempDirectory(__DIR__ . '/../temp'); $configurator->createRobotLoader() ->addDirectory(__DIR__) ->addDirectory(__DIR__ . '/../libs') ->register(); Анализатор PHP-файлов
RobotLoader можно также использовать исключительно для поиска классов, интерфейсов, трейтов и перечислений в PHP-файлах без использования функции автозагрузки:
$loader = new Nette\Loaders\RobotLoader; $loader->addDirectory(__DIR__ . '/app'); // просканирует каталоги на наличие классов / интерфейсов / трейтов / перечислений $loader->rebuild(); // возвращает массив пар класс => имя файла $res = $loader->getIndexedClasses(); Даже при таком использовании вы можете использовать кеш. Благодаря этому при повторном сканировании не будут повторно анализироваться неизмененные файлы:
$loader = new Nette\Loaders\RobotLoader; $loader->addDirectory(__DIR__ . '/app'); // установим кеширование в каталог 'temp' $loader->setTempDirectory(__DIR__ . '/temp'); // просканирует каталоги с использованием кеша $loader->refresh(); // возвращает массив пар класс => имя файла $res = $loader->getIndexedClasses(); Кеширование
RobotLoader очень быстр, потому что он умно использует кеш.
При разработке вы практически не замечаете, что он работает в фоновом режиме. Он постоянно обновляет кеш, так как учитывает, что классы и файлы могут создаваться, удаляться, переименовываться и т.д. И он повторно не сканирует файлы, которые не изменились.
При развертывании на production-сервере, наоборот, рекомендуется отключить обновление кеша с помощью $loader->setAutoRefresh(false) (в приложении Nette это происходит автоматически), так как файлы не меняются. При этом необходимо при загрузке новой версии на хостинг очистить кеш.
Первоначальное сканирование файлов, когда кеш еще не существует, может у более крупных приложений, естественно, занять некоторое время. RobotLoader имеет встроенную защиту от cache stampede. Это ситуация, когда на production-сервере собирается большое количество одновременных запросов, которые запускают RobotLoader, и поскольку кеш еще не существует, все они начали бы сканировать файлы. Что непропорционально нагрузило бы сервер. К счастью, RobotLoader работает так, что при нескольких одновременных запросах файлы индексирует только первый поток, создает кеш, остальные ждут и впоследствии используют кеш.
PSR-4
Сегодня для автозагрузки можно использовать Composer при соблюдении PSR-4. Проще говоря, это система, когда пространства имен и имена классов соответствуют структуре каталогов и именам файлов, то есть, например, App\Core\RouterFactory будет в файле /path/to/App/Core/RouterFactory.php.
RobotLoader не связан ни с какой фиксированной структурой, поэтому он подходит в ситуациях, когда вам не совсем удобно иметь одинаково спроектированную структуру каталогов, как пространства имен в PHP, или когда вы разрабатываете приложение, которое исторически таких соглашений не использует. Также возможно использовать оба загрузчика вместе.