RobotLoader: samodejno nalaganje razredov

RobotLoader je orodje, ki vam zagotavlja udobje samodejnega nalaganja razredov za celotno vašo aplikacijo, vključno s knjižnicami tretjih oseb.

  • znebimo se vseh require
  • nalagale se bodo samo potrebne skripte
  • ne zahteva strogih konvencij poimenovanja imenikov ali datotek
  • izjemno hitro
  • brez ročnega posodabljanja predpomnilnika, vse poteka samodejno
  • zrela, stabilna in široko uporabljana knjižnica

Lahko torej pozabimo na te znane bloke kode:

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

Namestitev

RobotLoader si lahko prenesete kot eno samostojno datoteko RobotLoader.php, ki jo vključite z require v svojo skripto in takoj imate na voljo udobno samodejno nalaganje za celotno aplikacijo.

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

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

Če gradite aplikacijo, ki uporablja Composer, ga lahko namestite z njim:

composer require nette/robot-loader

Uporaba

Podobno, kot Google robot pregleduje in indeksira spletne strani, tako tudi RobotLoader pregleduje vse PHP skripte in si beleži, katere razrede, vmesnike, lastnosti in enume je v njih našel. Rezultate iskanja si nato shrani v predpomnilnik in jih uporabi pri naslednji zahtevi. Dovolj je torej določiti, katere imenike naj pregleduje in kam naj shranjuje predpomnilnik:

$loader = new Nette\Loaders\RobotLoader;

// imeniki, ki jih naj RobotLoader indeksira (vključno s podimeniki)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');

// nastavimo predpomnjenje v imenik 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // zaženemo RobotLoader

In to je vse, od te točke naprej nam ni treba uporabljati require. Odlično!

Če RobotLoader med indeksiranjem naleti na podvojeno ime razreda, vrže izjemo in vas o tem obvesti. RobotLoader tudi samodejno posodobi predpomnilnik, ko mora naložiti razred, ki ga ne pozna. To priporočamo izklopiti na produkcijskih strežnikih, glejte #Predpomnjenje.

Če želite, da RobotLoader preskoči nekatere imenike, uporabite $loader->excludeDirectory('temp') (lahko kličete večkrat ali predate več imenikov).

Privzeto RobotLoader poroča o napakah v PHP datotekah z metanjem izjeme ParseError. To lahko potlačite z $loader->reportParseErrors(false).

Nette aplikacija

Znotraj Nette aplikacije, kjer se v zagonski datoteki Bootstrap.php uporablja objekt $configurator, lahko zapis poenostavimo:

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

Analizator PHP datotek

RobotLoader lahko uporabite tudi zgolj za iskanje razredov, vmesnikov, lastnosti in enumov v PHP datotekah brez uporabe funkcije samodejnega nalaganja:

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

// preišče imenike za razrede / vmesnike / lastnosti / enume
$loader->rebuild();

// vrne polje parov razred => ime datoteke
$res = $loader->getIndexedClasses();

Tudi pri takšni uporabi lahko izkoristite predpomnilnik. Zahvaljujoč temu pri ponovnem skeniranju ne bodo ponovno analizirane nespremenjene datoteke:

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

// nastavimo predpomnjenje v imenik 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');

// preišče imenike z uporabo predpomnilnika
$loader->refresh();

// vrne polje parov razred => ime datoteke
$res = $loader->getIndexedClasses();

Predpomnjenje

RobotLoader je zelo hiter, ker spretno uporablja predpomnilnik.

Med razvojem z njim praktično ne veste, da teče v ozadju. Sproti si posodablja predpomnilnik, ker računa s tem, da lahko razredi in datoteke nastajajo, izginjajo, se preimenujejo itd. In ponovno ne skenira datotek, ki se niso spremenile.

Pri namestitvi na produkcijskem strežniku pa nasprotno priporočamo izklop posodabljanja predpomnilnika z uporabo $loader->setAutoRefresh(false) (v Nette Aplikaciji se to zgodi samodejno), ker se datoteke ne spreminjajo. Hkrati je potem treba ob nalaganju nove različice na gostovanje izbrisati predpomnilnik.

Prvotno skeniranje datotek, ko predpomnilnik še ne obstaja, lahko pri obsežnejših aplikacijah seveda traja nekaj časa. RobotLoader ima vgrajeno preprečevanje pred cache stampede. Gre za situacijo, ko se na produkcijskem strežniku zbere večje število sočasnih zahtev, ki zaženejo RobotLoader, in ker predpomnilnik še ne obstaja, bi vsi začeli skenirati datoteke. Kar bi nesorazmerno obremenilo strežnik. Na srečo RobotLoader deluje tako, da pri več sočasnih zahtevah indeksira datoteke samo prva nit, ustvari predpomnilnik, ostali čakajo in nato predpomnilnik uporabijo.

PSR-4

Danes lahko za samodejno nalaganje uporabljate Composer ob upoštevanju PSR-4. Poenostavljeno rečeno gre za sistem, kjer imenski prostori in imena razredov ustrezajo strukturi imenikov in imenom datotek, torej npr. App\Core\RouterFactory bo v datoteki /path/to/App/Core/RouterFactory.php.

RobotLoader ni vezan na nobeno fiksno strukturo, zato je primeren v situacijah, ko vam popolnoma ne ustreza imeti enako zasnovano strukturo imenikov kot imenske prostore v PHP, ali ko razvijate aplikacijo, ki zgodovinsko takšnih konvencij ne uporablja. Možno je tudi uporabljati oba nalagalnika skupaj.

različica: 4.0