Chargement automatique de classes avancé avec PHP 5 Un chargement dynamique natif avec spl_autoload()

Depuis PHP 5.1.2, les développeurs nous simplifient un peu la vie et offrent une réponse toute prête au dilemme posé plus tôt.

Si aucune fonction __autoload() n'est définie, alors PHP utilisera la fonction native spl_autoload() par défaut à condition qu'on lui demande :

  1.     <?php
  2.     spl_autoload_register();


Son comportement est assez simple et se base sur une stratégie bien connue avec include et require : on cherche partout où la configuration dit de chercher, et on prend le premier trouvé. Pour ma fameuse MyClass, spl_autoload() va parcourir chaque répertoire définit dans la directive include_path à la recherche d'un fichier appelé MyClass.php ou MyClass.inc.

Les opérations sur le système de fichier ne sont pas très amies avec l'optimisation temporelle d'un script

On peut obtenir une solution proche de celle décrite dans le deuxième exemple avec deux avantages : d'une part l'implémentation sera légèrement plus rapide et plus souple, d'autre part, elle fera appel à des fonctions natives, donc écrites en C, et donc qui seront presque à tous les coups plus rapides que notre propre version de __autoload().


Tout ceci est bien entendu paramétrable. Pour modifier la liste des répertoires parcourus, on peut modifier la valeur de la directive include_path dans le php.ini, ou utiliser le couple de fonctions set_include_path() et get_include_path(). Il est également possible d'ajouter des extensions à la recherche grâce à spl_autoload_extensions().

Pour reprendre notre second exemple, on pourra l'implémenter ainsi :

   1.     <?php
  2.     define('CLASSES_DIR', 'myproject/classes');
  3.      
  4.     spl_autoload_extensions('.class.php');
  5.      
  6.     set_include_path(
  7.     CLASSES_DIR.'/core'.PATH_SEPARATOR.
  8.     CLASSES_DIR.'/tools'.PATH_SEPARATOR.
  9.     CLASSES_DIR.'/model'.PATH_SEPARATOR.
 10.     CLASSES_DIR.'/dblayer'.
 11.     PATH_SEPARATOR.get_include_path()
 12.     );
 13.      
 14.     spl_autoload_register();

On place nos répertoires en premier pour qu'ils soient prioritaires, sans oublier d'ajouter les valeurs déjà définies avec get_include_path(). Par ailleurs, il est nécessaire de modifier légèrement notre convention de nommage des fichiers : class.MyClass.php devient nécessairement MyClass.class.php. Finalement, tout ça n'est pas très satisfaisant : comme on l'a évoqué tout à l'heure, les opérations sur le système de fichier ne sont pas très amies avec l'optimisation temporelle d'un script.

Avec des tests correspondant à votre situation, vous pourrez probablement choisir entre l'implémentation suivante et celle proposée dans le troisième exemple.