19 avri

Utiliser Zend\Loader\Autoloader

Publié le 19/04/2012

L’autoloading est le processus PHP par lequel le système tente de charger une classe lorsqu’il la rencontre pour la première fois (via new ou class_exists) si elle n’a pas été déjà chargée via require ou include. L’autoload fonctionne en cherchant une méthode nommée __autoload ou en examinant chaque méthode enregistrée via spl_autoload_register.

Zend Framework 2 fournit un composant Zend\Loader\Autoloader pour l’autoloading de Zend Framework et de vos propres classes.

Qu’est-ce qui est fourni ?

L’autoloader de ZF2 fournit ce qui suit :

  • Autoloading via include_path compatible PSR-0
  • Autoloading via préfixes ou namespaces compatible PSR-0
  • Autoloading via class map, incluant un outil de génération de class map
  • Fabrique (NdT : Factory, un design pattern courant) d’autoloader pour pouvoir gérer plusieurs stratégies d’autoloading à la fois

Ces fonctionnalités sont fournies à travers deux classes : StandardAutoloader et ClassMapAutoloader.

Zend\Loader\StandardAutoloader

StandardAutoLoader implémente le chargement des classes en examinant leur nom et en cherchant un fichier sur le disque. Il peut mettre en oeuvre trois stratégies :

  • Chercher dans l’include_path
  • Charger depuis une liste de paires namespace / répertoire
  • Charger depuis une liste de paires préfixe vendeur (NdT vendor prefix) / répertoire

Ces stratégies peuvent être combinées pour une flexibilité maximale.

Exemple d’utilisation :

require_once ZF2_PATH . '/Loader/StandardAutoloader.php';<br /><br />$autoLoader = new ZendLoaderStandardAutoloader(array(<br />    'prefixes' =&gt; array(<br />        'MyVendor' =&gt; __DIR__ . '/MyVendor',<br />    ),<br />    'namespaces' =&gt; array(<br />        'MyNamespace' =&gt; __DIR__ . '/MyNamespace',<br />    ),<br />    'fallback_autoloader' =&gt; true,<br />));<br /><br />// register our StandardAutoloader with the SPL autoloader<br />$autoLoader-&gt;register(); <br />

La recherche dans l’include_path est la solution la plus lente, similaire au fonctionnement de l’autoloader de ZF1, et est connue comme solution de repli à utiliser en dernier ressort. :)

Après avoir configuré notre StandardAutoLoader et l’avoir enregistré, voici comment l’utiliser :

$test1 = new MyNamespaceTest();
$test2 = new MyVendor_Test();

Quelle différence entre préfixe et namespace ?

Le système à préfixe est utilisé pour les classes sans namespace, ces classes dont les répertoires sont séparés par le caractère souligné, comme par exemple Zend_Config_Ini. Un namespace est un namespace PHP 5.3 dont les répertoires sont séparés par le séparateur de namespace ou par des caractères souligné. Par exemple la classe MyNamespace\Sub_Test serait stockée dans /chemin/vers/MyNamespace/Sub/Test.php.

Interface de programmation

Vous pouvez aussi utiliser l’interface de programmation plutôt que de configurer le constructeur :

require_once ZF2_PATH . '/Loader/StandardAutoloader.php';<br /><br />$loader = new ZendLoaderStandardAutoloader();<br /><br />$loader-&gt;registerPrefix('MyVendor', __DIR__ . '/MyVendor')<br />       -&gt;registerNamespace('MyNamespace', __DIR__ . '/MyNamespace')<br />       -&gt;setFallbackAutoloader(true);<br />       <br />$loader-&gt;register(); <br />

Si vous avez de multiples préfixes ou namespaces, vous pouvez utiliser registerPrefixes et registerNamespaces qui prennent des tableaux.

Zend\Loader\ClassMapAutoloader

L’autoloader via class map est un autoloader de haute performance. Il utilise des class maps, qui sont de simples tableaux associatifs associant chaque nom de classe à un fichier sur le disque contenant cette classe. Cet autoloader est extrêmement rapide car son travail consiste en une simple recherche de clé dans le tableau. En fait, le code complet de la méthode autoload est le suivant :

public function autoload($class)<br />{<br />    if (isset($this-&gt;map[$class])) {<br />        include $this-&gt;map[$class];<br />    }<br />} <br />

Vous ne pouvez pas faire plus rapide qua ça ! Et ça fonctionne aussi avec le cache d’opcode PHP et les caches de realpath (NdT : cache de realpath est la traduction utilisée dans la documentation PHP).

Pour utiliser l’autoloader via class map, vous avez besoin d’un fichier de class map, autoload_classmap.php comme celui-ci :

&lt;?php <br />return array(<br />    'MyNamespaceTest' =&gt; __DIR__ .  '/MyNamespace/Test.php',<br />    'MyVendor_Test'    =&gt; __DIR__ .  '/MyVendor/Test.php',<br />); <br />

Vous pouvez utiliser l’autoloader via class map comme ceci :

require_once ZF2_PATH . '/Loader/ClassMapAutoloader.php';<br />        <br />$autoLoader = new ZendLoaderClassMapAutoloader(<br />    array(__DIR__ . '/autoload_classmap.php'));<br />        <br />// register with the SPL autoloader<br />$autoLoader-&gt;register(); &nbsp;<br />

Dans ce cas, vous ne pouvez charger que les classes qui sont listées dans le(s) fichier(s) fourni(s). Notez que, par convention, le fichier de class map est nommé autoload_classmap.php, mais pourrait être tout fichier renvoyant un tableau.

Notez que le constructeur permet de transmettre de multiples fichiers de map :

$loader = new ZendLoaderClassMapAutoloader(array(<br />    __DIR__ . '/../library/autoload_classmap.php',<br />    __DIR__ . '/../application/autoload_classmap.php',<br />)); <br />

Il existe également une méthode nommée registerAutoload() qui fait la même chose.

$loader = new ZendLoaderClassMapAutoloader();<br />$loader-&gt;registerAutoloadMap(array(<br />    __DIR__ . '/../library/autoload_classmap.php',<br />    __DIR__ . '/../application/autoload_classmap.php',<br />)); <br />

Notez que les nouvelles maps sont fusionnées à celles déjà enregistrées. La dernière définition d’une classe gagne. Par conséquent, vous pouvez surcharger la localisation d’une classe si nécessaire.

Créer des class maps

Comme vous pouvez l’imaginer, créer des class maps à la main peut vite devenir ennuyeux. Pour soulager le développeur, Zend Framework 2 fournit un script PHP, classmap_generator.php dans le répertoire bin, qui fera le travail pour vous. Cet outil scannera la sous-arborescence complète à partir du répertoire courant (ou de celui spécifié en option) et créera un fichier de class map pour chaque classe qu’il trouvera. Il est utilisé comme ceci :

prompt&gt; php path/to/zf2/bin/classmap_generator.php -w<br />Creating class file map for library in '/var/www/project/library'...<br />Wrote classmap file to '/var/www/project/library/autoload_classmap.php'

Je m’attends à ce que ZF2 soit distribué avec un autoload_classmap.php lorsqu’il sera distribué (NdT released).

Combiner les stratégies d’autoloading

ZF2 fournit également un AutoloaderFactory qui permet de combiner ClassMapAutoloaders et StandardAutoloaders. C’est particulièrement utile en phase de développement où vous souhaiterez utiliser ClassMapAutoloader pour ZF2 et StandardAutoloader pour vos propres fichiers. On l’utilise comme ceci :

require_once ZF2_PATH . '/Loader/AutoloaderFactory.php';<br />ZendLoaderAutoloaderFactory::factory(array(<br />    'ZendLoaderClassMapAutoloader' =&gt; array(<br />        __DIR__ . '/../library/Zend/autoload_classmap.php',<br />    ),<br />    'ZendLoaderStandardAutoloader' =&gt; array(<br />        'prefixes' =&gt; array(<br />            'MyVendor' =&gt; __DIR__ . '/MyVendor',<br />        ),<br />        'namespaces' =&gt; array(<br />            'MyNamespace' =&gt; __DIR__ . '/MyNamespace',<br />        ),<br />        'fallback_autoloader' =&gt; true,<br />    ),<br />)); <br />

Lorsque la méthode factory s’exécute, elle charge et initialise successivement chaque autoloader puis appelle la méthode register() via le système spl_autoload. Comme spl_autoload s’utilise comme une queue, il faut placer les autoloaders via class maps en premier car qu’ils rendent la main très vite en cas d’échec.

Notez que si vous utilisez la fabrique plusieurs fois d’affilée, pour ajouter des fichiers à l’autoloader via classmap par exemple, alors elle réutilisera l’instance de ClassMapAutoloader créée au départ.

Notes sur l’auteur :
Rob Allen est un expert PHP et Zend Framework basé dans le Worcester, au Royaume-Uni. Il est directeur technique pour Big Room Internet et auteur du livre Zend Framework in Action.

- 

Traduction de l’article "Using Zend\Loader\Autoloader" de Rob Allen, daté du 13 février 2012. Avec Accent Libre.

Partager cet article :

Vous souhaitez reproduire cet article ?