Nette Documentation Preview

syntax
RobotLoader: Автозагрузка классов
*********************************

<div class=perex>

RobotLoader - это инструмент, обеспечивающий удобство автоматической загрузки классов для всего приложения, включая библиотеки сторонних разработчиков.

- Исключите все утверждения `require`.
- Загружаются только необходимые скрипты
- Не требует строгих соглашений об именовании каталогов и файлов
- Чрезвычайно быстро
- Не нужно вручную обновлять кэш, все выполняется автоматически
- Зрелая, стабильная и широко используемая библиотека

</div>

Таким образом, мы можем забыть об этих привычных блоках кода:

```php
require_once 'Utils/Page.php';
require_once 'Utils/Style.php';
require_once 'Utils/Paginator.php';
//...
```


Установка .[#toc-installation]
------------------------------

Вы можете загрузить RobotLoader в виде [отдельного файла `RobotLoader.php` |https://github.com/nette/robot-loader/raw/standalone/src/RobotLoader/RobotLoader.php], который вы включаете с помощью `require` в свой скрипт и сразу же получаете удобную автозагрузку для всего приложения.

```php
require '/path/to/RobotLoader.php';

$loader = new Nette\Loaders\RobotLoader;
//...
```

Если вы собираете приложение с помощью [Composer |best-practices:composer], то установить его можно через:

```shell
composer require nette/robot-loader
```


Использование .[#toc-usage]
---------------------------

Подобно тому, как робот Google просматривает и индексирует веб-страницы, [RobotLoader |api:Nette\Loaders\RobotLoader] просматривает все PHP-скрипты и отмечает, какие классы, интерфейсы, трейты и перечисления он нашел. Затем он сохраняет результаты в кэше для использования при последующих запросах. Вам нужно только указать, по каким каталогам он должен пройти и где хранить кэш:

```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 также автоматически обновляет кэш, когда ему необходимо загрузить неизвестный класс. Мы рекомендуем отключить эту функцию на рабочих серверах, см. раздел " [Кэширование |#Caching]".

Если вы хотите, чтобы RobotLoader пропускал определенные каталоги, используйте команду `$loader->excludeDirectory('temp')` (может вызываться несколько раз или передавать несколько каталогов).

По умолчанию RobotLoader сообщает об ошибках в PHP-файлах, выбрасывая исключение `ParseError`. Это может быть подавлено с помощью `$loader->reportParseErrors(false)`.


Nette Application .[#toc-nette-application]
-------------------------------------------

Внутри Nette Application, где `$configurator` используется в `Bootstrap.php`, можно настроить RobotLoader таким образом:

```php
$configurator = new Nette\Bootstrap\Configurator;
//...
$configurator->setTempDirectory(__DIR__ . '/../temp');
$configurator->createRobotLoader()
	->addDirectory(__DIR__)
	->addDirectory(__DIR__ . '/../libs')
	->register();
```


Анализатор PHP-файлов .[#toc-php-files-analyzer]
------------------------------------------------

RobotLoader также может быть использован чисто для поиска классов, интерфейсов, трейтов и перечислений в PHP-файлах **без** использования функции автозагрузки:

```php
$loader = new Nette\Loaders\RobotLoader;
$loader->addDirectory(__DIR__ . '/app');

// Сканирует каталоги на наличие классов/интерфейсов/трайтов/энумов
$loader->rebuild();

// Возвращает массив пар класс => имя файла
$res = $loader->getIndexedClasses();
```

Даже при таком использовании можно использовать кэширование. Это гарантирует, что неизмененные файлы не будут сканироваться повторно:

```php
$loader = new Nette\Loaders\RobotLoader;
$loader->addDirectory(__DIR__ . '/app');

// Установить кэширование в каталог 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');

// Сканирование каталогов с использованием кэша
$loader->refresh();

// Возвращает массив пар класс => имя файла
$res = $loader->getIndexedClasses();
```


Кэширование .[#toc-caching]
---------------------------

RobotLoader работает очень быстро, поскольку в нем разумно используется кэширование.

Во время разработки вы едва ли заметите, что он работает в фоновом режиме. Он постоянно обновляет свой кэш, учитывая, что классы и файлы могут создаваться, удаляться, переименовываться и т.д. При этом повторное сканирование неизмененных файлов не производится.

На рабочем же сервере мы рекомендуем отключить обновление кэша с помощью `$loader->setAutoRefresh(false)` (в Nette Application это происходит автоматически), поскольку файлы не меняются. В то же время при загрузке новой версии на хостинг необходимо **очищать кэш**.

Первоначальное сканирование файлов, когда кэш еще не существует, естественно, может занять некоторое время для больших приложений. RobotLoader имеет встроенную защиту от "cache stampede":https://en.wikipedia.org/wiki/Cache_stampede.
Это ситуация, когда большое количество одновременных запросов на рабочем сервере вызовет RobotLoader, и поскольку кэш еще не существует, все они начнут сканировать файлы, что приведет к перегрузке сервера.
К счастью, RobotLoader работает таким образом, что только первый поток индексирует файлы, создает кэш, а остальные ждут и затем используют кэш.


PSR-4 .[#toc-psr-4]
-------------------

В настоящее время [для автозагрузки |best-practices:composer#autoloading] можно использовать [Composer |best-practices:composer#autoloading], придерживаясь при этом PSR-4. Проще говоря, это система, в которой пространства имен и имена классов соответствуют структуре каталогов и именам файлов, например, `App\Router\RouterFactory` будет находиться в файле `/path/to/App/Router/RouterFactory.php`.

RobotLoader не привязан к какой-либо фиксированной структуре, поэтому он полезен в ситуациях, когда не требуется, чтобы структура каталогов была оформлена в точном соответствии с пространствами имен PHP, или при разработке приложения, в котором исторически не используются подобные соглашения. Также возможно совместное использование обоих загрузчиков.


{{leftbar: nette:@menu-topics}}

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 также автоматически обновляет кэш, когда ему необходимо загрузить неизвестный класс. Мы рекомендуем отключить эту функцию на рабочих серверах, см. раздел " Кэширование".

Если вы хотите, чтобы RobotLoader пропускал определенные каталоги, используйте команду $loader->excludeDirectory('temp') (может вызываться несколько раз или передавать несколько каталогов).

По умолчанию RobotLoader сообщает об ошибках в PHP-файлах, выбрасывая исключение ParseError. Это может быть подавлено с помощью $loader->reportParseErrors(false).

Nette Application

Внутри Nette Application, где $configurator используется в Bootstrap.php, можно настроить RobotLoader таким образом:

$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 работает очень быстро, поскольку в нем разумно используется кэширование.

Во время разработки вы едва ли заметите, что он работает в фоновом режиме. Он постоянно обновляет свой кэш, учитывая, что классы и файлы могут создаваться, удаляться, переименовываться и т.д. При этом повторное сканирование неизмененных файлов не производится.

На рабочем же сервере мы рекомендуем отключить обновление кэша с помощью $loader->setAutoRefresh(false) (в Nette Application это происходит автоматически), поскольку файлы не меняются. В то же время при загрузке новой версии на хостинг необходимо очищать кэш.

Первоначальное сканирование файлов, когда кэш еще не существует, естественно, может занять некоторое время для больших приложений. RobotLoader имеет встроенную защиту от cache stampede. Это ситуация, когда большое количество одновременных запросов на рабочем сервере вызовет RobotLoader, и поскольку кэш еще не существует, все они начнут сканировать файлы, что приведет к перегрузке сервера. К счастью, RobotLoader работает таким образом, что только первый поток индексирует файлы, создает кэш, а остальные ждут и затем используют кэш.

PSR-4

В настоящее время для автозагрузки можно использовать Composer, придерживаясь при этом PSR-4. Проще говоря, это система, в которой пространства имен и имена классов соответствуют структуре каталогов и именам файлов, например, App\Router\RouterFactory будет находиться в файле /path/to/App/Router/RouterFactory.php.

RobotLoader не привязан к какой-либо фиксированной структуре, поэтому он полезен в ситуациях, когда не требуется, чтобы структура каталогов была оформлена в точном соответствии с пространствами имен PHP, или при разработке приложения, в котором исторически не используются подобные соглашения. Также возможно совместное использование обоих загрузчиков.