Nette RobotLoader

RobotLoader est un outil qui apporte le confort du chargement automatique des classes à toute votre application, bibliothèques tierces comprises.

  • Supprime tous les require
  • Seuls les scripts nécessaires sont chargés
  • N'impose aucune convention de nommage stricte pour les répertoires ni les fichiers
  • Extrêmement rapide
  • Aucune mise à jour manuelle du cache, tout se fait automatiquement
  • Bibliothèque mûre, stable et largement utilisée

Nous pouvons donc oublier ces blocs de code bien connus :

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

Installation

Vous pouvez télécharger RobotLoader sous forme d'un unique fichier autonome RobotLoader.php, l'inclure par require dans votre script et profiter aussitôt d'un autoloading confortable pour toute l'application.

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

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

Si vous construisez votre application avec Composer, vous pouvez l'installer ainsi :

composer require nette/robot-loader

Utilisation

Un peu comme le robot de Google parcourt et indexe les pages web, RobotLoader parcourt tous les scripts PHP et note quelles classes, interfaces, traits et enums il y a trouvés. Il enregistre ensuite ces trouvailles dans un cache et s'en sert pour les requêtes suivantes. Vous n'avez qu'à indiquer les répertoires à parcourir et l'endroit où stocker le cache :

$loader = new Nette\Loaders\RobotLoader;

// Directories for RobotLoader to index (including subdirectories)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');

// Set caching to the 'temp' directory
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // Activate RobotLoader

Et c'est tout ! À partir de là, vous n'avez plus besoin de require. Génial !

Si RobotLoader rencontre un nom de classe en double pendant l'indexation, il lève une exception et vous en avertit. RobotLoader met aussi automatiquement le cache à jour quand il doit charger une classe qu'il ne connaît pas. Nous conseillons de désactiver cela sur les serveurs de production, voir Caching.

Si vous voulez que RobotLoader saute certains répertoires, utilisez $loader->excludeDirectory('temp') (appelable plusieurs fois, ou en passant plusieurs répertoires).

Par défaut, RobotLoader ne parcourt que les fichiers d'extension .php. Pour indexer aussi d'autres types de fichiers, ajustez la propriété $acceptFiles, qui contient un tableau de masques :

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

La propriété $ignoreDirs contient de la même façon les masques des répertoires toujours sautés pendant le parcours (par défaut .*, *.old, *.bak, *.tmp, temp).

Par défaut, RobotLoader signale les erreurs des fichiers PHP en levant une exception ParseError. Cela peut être supprimé avec $loader->reportParseErrors(false).

Sous le capot, register() accroche la méthode tryLoad() à la chaîne d'autoloading de PHP. Chaque fois que PHP a besoin d'une classe, interface, trait ou enum inconnu, il passe le nom à $loader->tryLoad($type), qui trouve le fichier correspondant et l'inclut.

Nette Application

Dans une Nette Application, où l'objet $configurator est utilisé dans le fichier d'amorçage Bootstrap.php, la configuration peut être simplifiée :

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

Analyseur de fichiers PHP

RobotLoader peut aussi servir uniquement à trouver les classes, interfaces, traits et enums dans des fichiers PHP, sans utiliser la fonction d'autoloading :

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

// Scans directories for classes/interfaces/traits/enums
$loader->rebuild();

// Returns an array of class => filename pairs
$res = $loader->getIndexedClasses();

Même dans cet usage, vous pouvez profiter du cache. Les fichiers inchangés ne seront alors pas parcourus de nouveau :

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

// Set caching to the 'temp' directory
$loader->setTempDirectory(__DIR__ . '/temp');

// Scans directories using cache
$loader->refresh();

// Returns an array of class => filename pairs
$res = $loader->getIndexedClasses();

Caching

RobotLoader est très rapide, car il exploite habilement le cache.

Pendant le développement, vous remarquez à peine qu'il travaille en arrière-plan. Il met continuellement son cache à jour, en tenant compte du fait que des classes et des fichiers peuvent être créés, supprimés, renommés, etc. Et il ne reparcourt pas les fichiers qui n'ont pas changé.

Sur un serveur de production, à l'inverse, nous conseillons de désactiver la mise à jour du cache avec $loader->setAutoRefresh(false) (cela se fait automatiquement dans une Nette Application), car les fichiers n'y changent pas. En contrepartie, il faut vider le cache en déployant une nouvelle version chez l'hébergeur.

Le tout premier parcours des fichiers, quand le cache n'existe pas encore, peut naturellement prendre un moment pour les grosses applications. RobotLoader dispose d'une prévention intégrée du cache stampede. C'est la situation où un grand nombre de requêtes concurrentes déclenchent RobotLoader sur un serveur de production et où, faute de cache, elles se mettraient toutes à parcourir les fichiers, au risque de saturer le serveur. Heureusement, RobotLoader fonctionne de telle sorte qu'en cas de requêtes concurrentes, seul le premier thread indexe les fichiers et crée le cache, tandis que les autres attendent puis utilisent le cache produit.

PSR-4

De nos jours, vous pouvez utiliser Composer pour l'autoloading en respectant PSR-4. En clair, c'est un système où les espaces de noms et les noms de classes correspondent à l'arborescence des répertoires et aux noms des fichiers ; App\Core\RouterFactory se trouvera par exemple dans le fichier /path/to/App/Core/RouterFactory.php.

RobotLoader n'est lié à aucune structure fixe, il est donc utile quand vous ne voulez pas que l'arborescence des répertoires calque exactement les espaces de noms PHP, ou quand vous développez une application qui, historiquement, n'emploie pas ces conventions. Il est aussi possible d'utiliser les deux loaders ensemble.

Si vous passez à une version plus récente, consultez la page mise à niveau.

version: 4.x