Nette Documentation Preview

syntax
RobotLoader: Automatyczne ładowanie klas
****************************************

<div class=perex>

RobotLoader to narzędzie, które zapewnia komfort automatycznego ładowania klas dla całej aplikacji, w tym bibliotek innych firm.

- Wyeliminuj wszystkie instrukcje `require`
- Załadowane zostaną tylko niezbędne skrypty
- Nie wymaga ścisłych konwencji nazewnictwa katalogów lub plików
- Niezwykle szybki
- Brak ręcznych aktualizacji pamięci podręcznej, wszystko działa automatycznie
- Dojrzała, stabilna i szeroko stosowana biblioteka

</div>

Możemy więc zapomnieć o tych znanych blokach kodu:

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


Instalacja .[#toc-installation]
-------------------------------

RobotLoader można pobrać jako [pojedynczy samodzielny plik `RobotLoader.php` |https://github.com/nette/robot-loader/raw/standalone/src/RobotLoader/RobotLoader.php], który można dołączyć za pomocą `require` do skryptu i natychmiast cieszyć się wygodnym automatycznym ładowaniem całej aplikacji.

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

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

Jeśli budujesz aplikację przy użyciu [Composera |best-practices:composer], możesz zainstalować go za pośrednictwem:

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


Użycie .[#toc-usage]
--------------------

Podobnie jak robot Google przeszukuje i indeksuje strony internetowe, [RobotLoader |api:Nette\Loaders\RobotLoader] przechodzi przez wszystkie skrypty PHP i odnotowuje znalezione klasy, interfejsy, cechy i wyliczenia. Następnie przechowuje wyniki w pamięci podręcznej do wykorzystania w kolejnych żądaniach. Wystarczy określić, przez które katalogi ma przechodzić i gdzie przechowywać pamięć podręczną:

```php
$loader = new Nette\Loaders\RobotLoader;

// Katalogi do indeksowania przez RobotLoader (w tym podkatalogi)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');

// Ustaw buforowanie na katalog "temp
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // Aktywuj RobotLoader
```

I to wszystko, od tego momentu nie musimy używać `require`. Super!

Jeśli RobotLoader napotka zduplikowaną nazwę klasy podczas indeksowania, zgłosi wyjątek i powiadomi o tym użytkownika. RobotLoader automatycznie aktualizuje również pamięć podręczną, gdy musi załadować nieznaną klasę. Zalecamy wyłączenie tej opcji na serwerach produkcyjnych, patrz [Buforowanie |#Caching].

Jeśli chcesz, aby RobotLoader pomijał określone katalogi, użyj `$loader->excludeDirectory('temp')` (można wywołać wiele razy lub przekazać wiele katalogów).

Domyślnie RobotLoader zgłasza błędy w plikach PHP, rzucając wyjątek `ParseError`. Można to wyłączyć za pomocą `$loader->reportParseErrors(false)`.


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

Wewnątrz aplikacji Nette, gdzie `$configurator` jest używany w `Bootstrap.php`, można skonfigurować RobotLoader w ten sposób:

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


Analizator plików PHP .[#toc-php-files-analyzer]
------------------------------------------------

RobotLoader może być również używany wyłącznie do wyszukiwania klas, interfejsów, cech i wyliczeń w plikach PHP **bez** korzystania z funkcji automatycznego ładowania:

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

// Skanuje katalogi w poszukiwaniu klas/interfejsów/traits/enums
$loader->rebuild();

// Zwraca tablicę par klasa => nazwa pliku
$res = $loader->getIndexedClasses();
```

Nawet przy takim użyciu można wykorzystać buforowanie. Gwarantuje to, że niezmienione pliki nie będą ponownie skanowane:

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

// Ustawia buforowanie na katalog "temp
$loader->setTempDirectory(__DIR__ . '/temp');

// Skanuje katalogi przy użyciu pamięci podręcznej
$loader->refresh();

// Zwraca tablicę par klasa => nazwa pliku
$res = $loader->getIndexedClasses();
```


Buforowanie .[#toc-caching]
---------------------------

RobotLoader jest bardzo szybki, ponieważ sprytnie wykorzystuje buforowanie.

Podczas programowania prawie nie widać, że działa w tle. Stale aktualizuje swoją pamięć podręczną, biorąc pod uwagę, że klasy i pliki mogą być tworzone, usuwane, zmieniane nazwy itp. I nie skanuje ponownie niezmienionych plików.

Z drugiej strony na serwerze produkcyjnym zalecamy wyłączenie aktualizacji pamięci podręcznej za pomocą `$loader->setAutoRefresh(false)` (w aplikacji Nette dzieje się to automatycznie), ponieważ pliki się nie zmieniają. Jednocześnie konieczne jest **wyczyszczenie pamięci podręcznej** podczas przesyłania nowej wersji na hosting.

Początkowe skanowanie plików, gdy pamięć podręczna jeszcze nie istnieje, może oczywiście zająć chwilę w przypadku większych aplikacji. RobotLoader ma wbudowaną ochronę przed "cache stampede":https://en.wikipedia.org/wiki/Cache_stampede.
Jest to sytuacja, w której duża liczba jednoczesnych żądań na serwerze produkcyjnym uruchomiłaby RobotLoader, a ponieważ pamięć podręczna jeszcze nie istnieje, wszystkie zaczęłyby skanować pliki, co przeciążyłoby serwer.
Na szczęście RobotLoader działa w taki sposób, że tylko pierwszy wątek indeksuje pliki, tworzy pamięć podręczną, a reszta czeka, a następnie korzysta z pamięci podręcznej.


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

Obecnie można używać [Composera do automatycznego ładowania |best-practices:composer#autoloading] przy jednoczesnym przestrzeganiu PSR-4. Mówiąc najprościej, jest to system, w którym przestrzenie nazw i nazwy klas odpowiadają strukturze katalogów i nazwom plików, np. `App\Core\RouterFactory` będzie w pliku `/path/to/App/Core/RouterFactory.php`.

RobotLoader nie jest powiązany z żadną stałą strukturą, więc jest przydatny w sytuacjach, w których nie chcesz, aby struktura katalogów była zaprojektowana dokładnie tak, jak przestrzenie nazw PHP, lub podczas tworzenia aplikacji, która historycznie nie używa takich konwencji. Możliwe jest również użycie obu programów ładujących razem.


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

RobotLoader: Automatyczne ładowanie klas

RobotLoader to narzędzie, które zapewnia komfort automatycznego ładowania klas dla całej aplikacji, w tym bibliotek innych firm.

  • Wyeliminuj wszystkie instrukcje require
  • Załadowane zostaną tylko niezbędne skrypty
  • Nie wymaga ścisłych konwencji nazewnictwa katalogów lub plików
  • Niezwykle szybki
  • Brak ręcznych aktualizacji pamięci podręcznej, wszystko działa automatycznie
  • Dojrzała, stabilna i szeroko stosowana biblioteka

Możemy więc zapomnieć o tych znanych blokach kodu:

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

Instalacja

RobotLoader można pobrać jako pojedynczy samodzielny plik RobotLoader.php, który można dołączyć za pomocą require do skryptu i natychmiast cieszyć się wygodnym automatycznym ładowaniem całej aplikacji.

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

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

Jeśli budujesz aplikację przy użyciu Composera, możesz zainstalować go za pośrednictwem:

composer require nette/robot-loader

Użycie

Podobnie jak robot Google przeszukuje i indeksuje strony internetowe, RobotLoader przechodzi przez wszystkie skrypty PHP i odnotowuje znalezione klasy, interfejsy, cechy i wyliczenia. Następnie przechowuje wyniki w pamięci podręcznej do wykorzystania w kolejnych żądaniach. Wystarczy określić, przez które katalogi ma przechodzić i gdzie przechowywać pamięć podręczną:

$loader = new Nette\Loaders\RobotLoader;

// Katalogi do indeksowania przez RobotLoader (w tym podkatalogi)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');

// Ustaw buforowanie na katalog "temp
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // Aktywuj RobotLoader

I to wszystko, od tego momentu nie musimy używać require. Super!

Jeśli RobotLoader napotka zduplikowaną nazwę klasy podczas indeksowania, zgłosi wyjątek i powiadomi o tym użytkownika. RobotLoader automatycznie aktualizuje również pamięć podręczną, gdy musi załadować nieznaną klasę. Zalecamy wyłączenie tej opcji na serwerach produkcyjnych, patrz Buforowanie.

Jeśli chcesz, aby RobotLoader pomijał określone katalogi, użyj $loader->excludeDirectory('temp') (można wywołać wiele razy lub przekazać wiele katalogów).

Domyślnie RobotLoader zgłasza błędy w plikach PHP, rzucając wyjątek ParseError. Można to wyłączyć za pomocą $loader->reportParseErrors(false).

Aplikacja Nette

Wewnątrz aplikacji Nette, gdzie $configurator jest używany w Bootstrap.php, można skonfigurować RobotLoader w ten sposób:

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

Analizator plików PHP

RobotLoader może być również używany wyłącznie do wyszukiwania klas, interfejsów, cech i wyliczeń w plikach PHP bez korzystania z funkcji automatycznego ładowania:

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

// Skanuje katalogi w poszukiwaniu klas/interfejsów/traits/enums
$loader->rebuild();

// Zwraca tablicę par klasa => nazwa pliku
$res = $loader->getIndexedClasses();

Nawet przy takim użyciu można wykorzystać buforowanie. Gwarantuje to, że niezmienione pliki nie będą ponownie skanowane:

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

// Ustawia buforowanie na katalog "temp
$loader->setTempDirectory(__DIR__ . '/temp');

// Skanuje katalogi przy użyciu pamięci podręcznej
$loader->refresh();

// Zwraca tablicę par klasa => nazwa pliku
$res = $loader->getIndexedClasses();

Buforowanie

RobotLoader jest bardzo szybki, ponieważ sprytnie wykorzystuje buforowanie.

Podczas programowania prawie nie widać, że działa w tle. Stale aktualizuje swoją pamięć podręczną, biorąc pod uwagę, że klasy i pliki mogą być tworzone, usuwane, zmieniane nazwy itp. I nie skanuje ponownie niezmienionych plików.

Z drugiej strony na serwerze produkcyjnym zalecamy wyłączenie aktualizacji pamięci podręcznej za pomocą $loader->setAutoRefresh(false) (w aplikacji Nette dzieje się to automatycznie), ponieważ pliki się nie zmieniają. Jednocześnie konieczne jest wyczyszczenie pamięci podręcznej podczas przesyłania nowej wersji na hosting.

Początkowe skanowanie plików, gdy pamięć podręczna jeszcze nie istnieje, może oczywiście zająć chwilę w przypadku większych aplikacji. RobotLoader ma wbudowaną ochronę przed cache stampede. Jest to sytuacja, w której duża liczba jednoczesnych żądań na serwerze produkcyjnym uruchomiłaby RobotLoader, a ponieważ pamięć podręczna jeszcze nie istnieje, wszystkie zaczęłyby skanować pliki, co przeciążyłoby serwer. Na szczęście RobotLoader działa w taki sposób, że tylko pierwszy wątek indeksuje pliki, tworzy pamięć podręczną, a reszta czeka, a następnie korzysta z pamięci podręcznej.

PSR-4

Obecnie można używać Composera do automatycznego ładowania przy jednoczesnym przestrzeganiu PSR-4. Mówiąc najprościej, jest to system, w którym przestrzenie nazw i nazwy klas odpowiadają strukturze katalogów i nazwom plików, np. App\Core\RouterFactory będzie w pliku /path/to/App/Core/RouterFactory.php.

RobotLoader nie jest powiązany z żadną stałą strukturą, więc jest przydatny w sytuacjach, w których nie chcesz, aby struktura katalogów była zaprojektowana dokładnie tak, jak przestrzenie nazw PHP, lub podczas tworzenia aplikacji, która historycznie nie używa takich konwencji. Możliwe jest również użycie obu programów ładujących razem.