RobotLoader: autoloadowanie klas

RobotLoader to narzędzie, które daje wygodę automatycznego ładowania klas dla całej aplikacji, w tym bibliotek firm trzecich.

  • Pozbywamy się wszystkich require
  • zostaną załadowane tylko niezbędne skrypty
  • nie wymaga ścisłych konwencji nazewnictwa dla katalogów i plików

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

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

Instalacja

Pobierz i zainstaluj bibliotekę za pomocą Composera:

composer require nette/robot-loader

Korzystanie z

Podobnie jak robot Google indeksuje strony internetowe, RobotLoader przeszukuje wszystkie skrypty PHP i notuje, jakie klasy, interfejsy i cechy w nich znalazł. Następnie buforuje wyniki swojej eksploracji i używa ich w następnym żądaniu. Wystarczy więc określić, które katalogi mają być indeksowane i gdzie mają być buforowane:

$loader = new Nette\Loaders\RobotLoader;

// katalogi, które mają być indeksowane przez RobotLoader (łącznie z podkatalogami)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');

// ustaw buforowanie w katalogu 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // uruchom RobotLoader

To wszystko, od tej pory nie musimy używać require. Świetnie!

Jeśli RobotLoader napotka zduplikowaną nazwę klasy podczas indeksowania, rzuca wyjątek i informuje o tym. RobotLoader również automatycznie aktualizuje pamięć podręczną, gdy musi załadować klasę, której nie zna. Zalecamy wyłączenie tego na serwerach produkcyjnych, zobacz Caching.

Jeśli chcesz, aby RobotLoader pominął niektóre katalogi, użyj $loader->excludeDirectory('temp') (możesz wykonać wiele połączeń lub przekazać wiele katalogów).

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

Aplikacje Nette

Wewnątrz aplikacji Nette, gdzie w pliku startowym używany jest obiekt Bootstrap.php $configurator , notacja może być uproszczona:

$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żyty do wyszukiwania klas, interfejsów i cech w plikach PHP bez użycia funkcji autoloadingu:

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

// skanuje katalogi w poszukiwaniu klas/interfejsów/traitów
$loader->rebuild();

// zwraca tablicę par class => filename
$res = $loader->getIndexedClasses();

W ten sposób można również wykorzystać cache. Dzięki temu niezmienione pliki nie będą ponownie analizowane przy ponownym skanowaniu:

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

// skanuje katalogi używając pamięci podręcznej
$loader->refresh();

// zwraca tablicę par class => filename
$res = $loader->getIndexedClasses();

Caching

RobotLoader jest bardzo szybki, ponieważ sprytnie wykorzystuje buforowanie.

Rozwijając się z nim, jesteś praktycznie nieświadomy, że działa on w tle. Stale aktualizuje swoją pamięć podręczną, ponieważ bierze pod uwagę, że klasy i pliki mogą być tworzone, znikać, zmieniać nazwy itp. I nie skanuje wielokrotnie plików, które nie uległy zmianie.

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

Początkowe skanowanie plików, gdy pamięć podręczna jeszcze nie istnieje, może zająć chwilę w przypadku większych aplikacji. RobotLoader ma wbudowane zapobieganie przed cache stampede. Jest to sytuacja, w której duża liczba współbieżnych żądań spotyka się na serwerze produkcyjnym i uruchamia RobotLoader, a ponieważ pamięć podręczna jeszcze nie istnieje, wszystkie zaczęłyby skanować pliki. Co spowodowałoby nieproporcjonalne obciążenie serwera. Na szczęście sposób działania RobotLoader polega na tym, że gdy istnieje wiele współbieżnych żądań, tylko pierwszy wątek indeksuje pliki, tworzy pamięć podręczną, pozostałe czekają, a następnie używają pamięci podręcznej.

PSR-4

Dziś Composer może być używany do autoloadingu, jeśli przestrzega się PSR-4. Najprościej mówiąc, jest to system, w którym przestrzenie nazw i nazwy klas odpowiadają strukturom katalogów i nazwom plików, więc na przykład App\Router\RouterFactory będzie w pliku /path/to/App/Router/RouterFactory.php.

RobotLoader nie jest przywiązany do żadnej stałej struktury, więc jest przydatny w sytuacjach, gdy nie czujesz się komfortowo z posiadaniem struktury katalogów zaprojektowanej w taki sam sposób jak przestrzenie nazw PHP, lub gdy rozwijasz aplikację, która historycznie nie używała takich konwencji. Możliwe jest również stosowanie obu ładowarek razem.

wersja: 4.0