RobotLoader : autoloading des classes

RobotLoader est un outil qui vous assure le confort du chargement automatique des classes pour toute votre application, y compris les bibliothèques tierces.

  • débarrassez-vous de tous les require
  • seuls les scripts nécessaires seront chargés
  • ne nécessite pas de conventions strictes de nommage des répertoires ou des fichiers
  • extrêmement rapide
  • aucune mise à jour manuelle du cache, tout se fait automatiquement
  • bibliothèque mature, stable et largement utilisée

Nous pouvons donc oublier ces blocs de code familiers :

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

Installation

Vous pouvez télécharger RobotLoader comme un seul fichier autonome RobotLoader.php, que vous incluez à l'aide de require dans votre script et vous disposez immédiatement d'un autoloading confortable pour toute l'application.

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

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

Si vous construisez une application utilisant Composer, vous pouvez l'installer via celui-ci :

composer require nette/robot-loader

Utilisation

De la même manière qu'un robot Google parcourt et indexe les pages web, RobotLoader parcourt tous les scripts PHP et enregistre les classes, interfaces, traits et enums qu'il y trouve. Il stocke ensuite les résultats de ses recherches dans un cache et les utilise lors de la prochaine requête. Il suffit donc de spécifier quels répertoires il doit parcourir et où stocker le cache :

$loader = new Nette\Loaders\RobotLoader;

// répertoires que RobotLoader doit indexer (y compris les sous-répertoires)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');

// nous définissons la mise en cache dans le répertoire 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // démarrons RobotLoader

Et c'est tout, à partir de maintenant, nous n'avons plus besoin d'utiliser require. Génial !

Si RobotLoader rencontre un nom de classe dupliqué lors de l'indexation, il lèvera une exception et vous en informera. RobotLoader met également à jour automatiquement le cache lorsqu'il doit charger une classe qu'il ne connaît pas. Nous recommandons de désactiver cela sur les serveurs de production, voir Mise en cache.

Si vous souhaitez que RobotLoader ignore certains répertoires, utilisez $loader->excludeDirectory('temp') (peut être appelé plusieurs fois ou passer plusieurs répertoires).

Par défaut, RobotLoader signale les erreurs dans les fichiers PHP en levant une exception ParseError. Cela peut être supprimé à l'aide de $loader->reportParseErrors(false).

Application Nette

À l'intérieur d'une application Nette, où l'objet $configurator est utilisé dans le fichier de démarrage Bootstrap.php, l'écriture 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 également être utilisé uniquement pour rechercher des classes, interfaces, traits et enums dans des fichiers PHP sans utiliser la fonction d'autoloading :

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

// parcourt les répertoires à la recherche de classes / interfaces / traits / enums
$loader->rebuild();

// retourne un tableau de paires classe => nom de fichier
$res = $loader->getIndexedClasses();

Même avec une telle utilisation, vous pouvez utiliser le cache. Grâce à cela, lors d'une nouvelle analyse, les fichiers inchangés ne seront pas analysés à nouveau :

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

// nous définissons la mise en cache dans le répertoire 'temp'
$loader->setTempDirectory(__DIR__ . '/temp');

// parcourt les répertoires en utilisant le cache
$loader->refresh();

// retourne un tableau de paires classe => nom de fichier
$res = $loader->getIndexedClasses();

Mise en cache

RobotLoader est très rapide car il utilise intelligemment le cache.

Pendant le développement, vous ne réalisez pratiquement pas qu'il s'exécute en arrière-plan. Il met à jour continuellement son cache, car il s'attend à ce que des classes et des fichiers puissent être créés, supprimés, renommés, etc. Et il ne scanne pas à plusieurs reprises les fichiers qui n'ont pas changé.

Lors du déploiement sur un serveur de production, nous recommandons au contraire de désactiver la mise à jour du cache à l'aide de $loader->setAutoRefresh(false) (dans une application Nette, cela se fait automatiquement), car les fichiers ne changent pas. En même temps, il est alors nécessaire de supprimer le cache lors du téléversement d'une nouvelle version sur l'hébergement.

L'analyse initiale des fichiers, lorsque le cache n'existe pas encore, peut naturellement prendre un certain temps pour les applications plus volumineuses. RobotLoader intègre une prévention contre le cache stampede. Il s'agit d'une situation où un grand nombre de requêtes simultanées arrivent sur le serveur de production, lancent RobotLoader, et comme le cache n'existe pas encore, elles commenceraient toutes à scanner les fichiers. Ce qui surchargerait indûment le serveur. Heureusement, RobotLoader fonctionne de telle sorte que lors de plusieurs requêtes simultanées, seul le premier thread indexe les fichiers, crée le cache, les autres attendent et utilisent ensuite le cache.

PSR-4

Aujourd'hui, il est possible d'utiliser Composer pour l'autoloading en respectant PSR-4. En termes simples, il s'agit d'un système où les espaces de noms et les noms de classes correspondent à la structure des répertoires et aux noms de fichiers, par exemple App\Core\RouterFactory sera dans le fichier /path/to/App/Core/RouterFactory.php.

RobotLoader n'est lié à aucune structure fixe, il est donc utile dans les situations où avoir une structure de répertoires conçue de la même manière que les espaces de noms en PHP ne vous convient pas tout à fait, ou lorsque vous développez une application qui n'utilise historiquement pas de telles conventions. Il est également possible d'utiliser les deux chargeurs ensemble.

version: 4.0