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]
------------------------------

```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(); // Run the RobotLoader
```

И это всё. С этого момента вам не нужно использовать `require`. Здорово, не так ли?

Когда RobotLoader сталкивается с дублированием имени класса во время индексирования, он выбрасывает исключение и сообщает вам об этом. RobotLoader также автоматически обновляет кэш, когда ему нужно загрузить неизвестный ему класс. Мы рекомендуем отключить это на производственных серверах, см. [#Кэширование].

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

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


Приложение Nette .[#toc-nette-application]
------------------------------------------

Внутри приложения Nette, где `$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');
$loader->setTempDirectory(__DIR__ . '/temp');

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

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


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

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

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

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

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


PSR-4
-----

Сегодня 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';
// ...

Установка

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(); // Run the RobotLoader

И это всё. С этого момента вам не нужно использовать require. Здорово, не так ли?

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

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

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

Приложение Nette

Внутри приложения Nette, где $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');
$loader->setTempDirectory(__DIR__ . '/temp');

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

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

Кэширование

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

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

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

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

PSR-4

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

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