Nette RobotLoader

RobotLoader è uno strumento che offre la comodità del caricamento automatico delle classi per tutta la vostra applicazione, librerie di terze parti comprese.

  • Elimina tutte le istruzioni require
  • Vengono caricati solo gli script necessari
  • Non richiede convenzioni di denominazione rigide per directory e file
  • Estremamente veloce
  • Nessun aggiornamento manuale della cache, tutto avviene automaticamente
  • Libreria matura, stabile e ampiamente usata

Possiamo quindi dimenticare questi blocchi di codice ben noti:

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

Installazione

Potete scaricare RobotLoader come unico file autonomo RobotLoader.php, includerlo con require nel vostro script e godervi subito il comodo autoloading per tutta l'applicazione.

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

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

Se costruite un'applicazione con Composer, potete installarlo con:

composer require nette/robot-loader

Uso

Come il robot di Google percorre e indicizza le pagine web, RobotLoader percorre tutti gli script PHP e registra quali classi, interfacce, trait ed enum ha trovato. Salva poi questi risultati in una cache e li usa per le richieste successive. Dovete solo indicare quali directory deve esaminare e dove salvare la cache:

$loader = new Nette\Loaders\RobotLoader;

// directory che RobotLoader deve indicizzare (sottodirectory comprese)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');

// impostiamo la cache nella directory 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // attiviamo RobotLoader

Ecco fatto! Da questo momento non dovete più usare require. Fantastico!

Se durante l'indicizzazione RobotLoader incontra un nome di classe duplicato, lancia un'eccezione e ve lo segnala. RobotLoader aggiorna inoltre automaticamente la cache quando deve caricare una classe che non conosce. Sui server di produzione consigliamo di disattivarlo, vedi Cache.

Se volete che RobotLoader salti certe directory, usate $loader->excludeDirectory('temp') (si può chiamare più volte oppure passare più directory).

Per impostazione predefinita RobotLoader esamina solo i file con estensione .php. Per indicizzare anche altri tipi di file, modificate la proprietà $acceptFiles, che contiene un array di maschere:

$loader->acceptFiles = ['*.php', '*.inc'];

La proprietà $ignoreDirs contiene in modo analogo le maschere delle directory che vengono sempre saltate durante la scansione (per impostazione predefinita .*, *.old, *.bak, *.tmp, temp).

Per impostazione predefinita RobotLoader segnala gli errori nei file PHP lanciando un'eccezione ParseError. Lo si può sopprimere con $loader->reportParseErrors(false).

Sotto il cofano register() aggancia il metodo tryLoad() alla catena di autoloading di PHP. Ogni volta che PHP ha bisogno di una classe, interfaccia, trait o enum sconosciuta, passa il nome a $loader->tryLoad($type), che trova il file corrispondente e lo include.

Nette Application

Dentro un'applicazione Nette, dove nel file di avvio Bootstrap.php si usa l'oggetto $configurator, l'impostazione si può semplificare:

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

Analizzatore di file PHP

RobotLoader si può usare anche solo per trovare classi, interfacce, trait ed enum nei file PHP senza usare la funzione di autoloading:

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

// esamina le directory in cerca di classi/interfacce/trait/enum
$loader->rebuild();

// restituisce un array di coppie classe => nome del file
$res = $loader->getIndexedClasses();

Anche con questo uso potete sfruttare la cache. Così i file non modificati non verranno riesaminati:

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

// impostiamo la cache nella directory 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');

// esamina le directory usando la cache
$loader->refresh();

// restituisce un array di coppie classe => nome del file
$res = $loader->getIndexedClasses();

Cache

RobotLoader è molto veloce perché usa la cache in modo intelligente.

Durante lo sviluppo quasi non vi accorgete che gira in background. Aggiorna continuamente la propria cache, tenendo conto che le classi e i file possono essere creati, cancellati, rinominati ecc. E non riesamina i file che non sono cambiati.

Su un server di produzione, al contrario, consigliamo di disattivare l'aggiornamento della cache con $loader->setAutoRefresh(false) (in un'applicazione Nette avviene automaticamente), perché i file non cambiano. Allo stesso tempo è necessario svuotare la cache quando caricate una nuova versione sull'hosting.

La prima scansione dei file, quando la cache non esiste ancora, può naturalmente richiedere un momento nelle applicazioni più grandi. RobotLoader ha una prevenzione integrata contro il cache stampede. È la situazione in cui un gran numero di richieste concorrenti su un server di produzione attiva RobotLoader e, poiché la cache non esiste ancora, tutte comincerebbero a esaminare i file, sovraccaricando magari il server. Per fortuna RobotLoader funziona in modo che, con più richieste concorrenti, solo il primo thread indicizza i file e crea la cache, mentre gli altri aspettano e poi usano la cache generata.

PSR-4

Oggi potete usare Composer per l'autoloading rispettando lo standard PSR-4. In parole semplici, è un sistema in cui i namespace e i nomi delle classi corrispondono alla struttura delle directory e ai nomi dei file, per esempio App\Core\RouterFactory sarà nel file /percorso/verso/App/Core/RouterFactory.php.

RobotLoader non è legato ad alcuna struttura fissa, quindi torna utile nelle situazioni in cui non volete che la struttura delle directory corrisponda esattamente ai namespace PHP, oppure quando sviluppate un'applicazione che storicamente non usa queste convenzioni. Si possono anche usare entrambi i loader insieme.

Se state aggiornando a una versione più recente, guardate la pagina aggiornamento.

versione: 4.x