RobotLoader: autoloading delle classi
RobotLoader è uno strumento che ti offre il comfort dell'autoloading automatico delle classi per l'intera applicazione, comprese le librerie di terze parti.
- ci liberiamo di tutti i
require
- verranno caricati solo gli script necessari
- non richiede convenzioni rigide per la denominazione di directory o file
- estremamente veloce
- nessun aggiornamento manuale della cache, tutto avviene automaticamente
- libreria matura, stabile e ampiamente utilizzata
Possiamo quindi dimenticare questi noti blocchi di codice:
require_once 'Utils/Page.php';
require_once 'Utils/Style.php';
require_once 'Utils/Paginator.php';
// ...
Installazione
Puoi scaricare RobotLoader come un singolo file autonomo
RobotLoader.php
, che includi con require
nel tuo script e hai subito a disposizione un comodo
autoloading per l'intera applicazione.
require '/path/to/RobotLoader.php';
$loader = new Nette\Loaders\RobotLoader;
// ...
Se stai costruendo un'applicazione utilizzando Composer, puoi installarlo tramite esso:
composer require nette/robot-loader
Utilizzo
Similmente a come il robot di Google scansiona e indicizza le pagine web, anche RobotLoader scansiona tutti gli script PHP e registra quali classi, interfacce, trait ed enum vi ha trovato. I risultati della ricerca vengono quindi salvati nella cache e utilizzati nella richiesta successiva. Basta quindi specificare quali directory deve scansionare e dove salvare la cache:
$loader = new Nette\Loaders\RobotLoader;
// directory che RobotLoader deve indicizzare (incluse le sottodirectory)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');
// impostiamo il caching nella directory 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // avviamo RobotLoader
E questo è tutto, da questo momento non dobbiamo più usare require
. Fantastico!
Se RobotLoader incontra un nome di classe duplicato durante l'indicizzazione, lancerà un'eccezione e ti informerà. RobotLoader aggiorna anche automaticamente la cache quando deve caricare una classe che non conosce. Consigliamo di disattivarlo sui server di produzione, vedi Caching.
Se vuoi che RobotLoader salti alcune directory, usa $loader->excludeDirectory('temp')
(può essere chiamato
più volte o passare più directory).
Per impostazione predefinita, RobotLoader segnala gli errori nei file PHP lanciando un'eccezione ParseError
.
Questo può essere soppresso usando $loader->reportParseErrors(false)
.
Applicazione Nette
All'interno di un'applicazione Nette, dove nel file di avvio Bootstrap.php
viene utilizzato l'oggetto
$configurator
, la scrittura può essere semplificata:
$configurator = new Nette\Bootstrap\Configurator;
// ...
$configurator->setTempDirectory(__DIR__ . '/../temp');
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->addDirectory(__DIR__ . '/../libs')
->register();
Analizzatore di file PHP
RobotLoader può anche essere utilizzato puramente per cercare classi, interfacce, trait ed enum nei file PHP senza utilizzare la funzione di autoloading:
$loader = new Nette\Loaders\RobotLoader;
$loader->addDirectory(__DIR__ . '/app');
// scansiona le directory per classi / interfacce / trait / enum
$loader->rebuild();
// restituisce un array di coppie classe => nome file
$res = $loader->getIndexedClasses();
Anche con questo utilizzo, puoi sfruttare la cache. Grazie a ciò, durante la nuova scansione, i file non modificati non verranno analizzati ripetutamente:
$loader = new Nette\Loaders\RobotLoader;
$loader->addDirectory(__DIR__ . '/app');
// impostiamo il caching nella directory 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');
// scansiona le directory utilizzando la cache
$loader->refresh();
// restituisce un array di coppie classe => nome file
$res = $loader->getIndexedClasses();
Caching
RobotLoader è molto veloce perché utilizza abilmente la cache.
Durante lo sviluppo, praticamente non ti accorgi che gira in background. Aggiorna continuamente la cache, perché tiene conto del fatto che classi e file possono nascere, morire, essere rinominati, ecc. E non scansiona ripetutamente i file che non sono cambiati.
Al contrario, durante la distribuzione su un server di produzione, consigliamo di disattivare l'aggiornamento della cache
usando $loader->setAutoRefresh(false)
(in un'applicazione Nette questo avviene automaticamente), perché i file
non cambiano. Allo stesso tempo, è quindi necessario cancellare la cache sull'hosting quando si carica una nuova
versione.
La scansione iniziale dei file, quando la cache non esiste ancora, può ovviamente richiedere un po' di tempo per applicazioni più grandi. RobotLoader ha una prevenzione integrata contro la cache stampede. Si tratta di una situazione in cui un numero maggiore di richieste simultanee arriva sul server di produzione, che avviano RobotLoader, e poiché la cache non esiste ancora, inizierebbero tutte a scansionare i file. Ciò sovraccaricherebbe eccessivamente il server. Fortunatamente, RobotLoader funziona in modo tale che, in caso di più richieste simultanee, solo il primo thread indicizza i file, crea la cache, gli altri attendono e successivamente utilizzano la cache.
PSR-4
Oggi è possibile utilizzare Composer per
l'autoloading rispettando PSR-4. In parole povere, si tratta di un sistema in cui i namespace e i nomi delle classi
corrispondono alla struttura delle directory e ai nomi dei file, ad esempio App\Core\RouterFactory
sarà nel file
/path/to/App/Core/RouterFactory.php
.
RobotLoader non è legato a nessuna struttura fissa, quindi è utile in situazioni in cui non ti va completamente bene avere la stessa struttura di directory progettata come i namespace in PHP, o quando sviluppi un'applicazione che storicamente non utilizza tali convenzioni. È anche possibile utilizzare entrambi i loader insieme.