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.