Chargement automatique de classes avancé avec PHP 5 PHP 5.3 et les namespaces pour simplifier tout ça

La dernière solution que je vais développer utilise une nouvelle notion introduite dans PHP 5.3. C'est une version simplifiée de la précédente, et que j'envisage d'utiliser dans la plupart des projets en PHP 5.3 sur lesquels je travaillerais.

Calquer l'organisation des fichiers avec l'organisation choisie pour les espaces de nom

L'utilisation des namespaces (ou espaces de noms en français) permet d'organiser logiquement les classes en modules, afin d'éviter les collisions entre plusieurs classes portant le même nom. Par analogie, il est souvent intéressant de calquer l'organisation des fichiers avec l'organisation choisie pour les espaces de nom.

Avec les espaces de nom, une classe possède un nom absolu sous la forme namespace\subnamespace\MyClass. on aurait donc les classes et namespaces suivants :

 namespace MyApp
 - MyApp\Request
 -MyApp\Config
 -MyApp\Context
 namespace View
 - View\Template
 - View\Cache
 namespace Db
 - Db\Connection
 namespace Easing
 - Easing\Email

Notre fonction de chargement automatique sera :

   1.     <?php
  2.     define('SOURCES_DIR', 'myproject/sources');
  3.     myapp_autoload($classname)
  4.     {
  5.       // Au passage, pensez à échapper le caractère \ !
  6.       $classname = explode('\\', $classname);
  7.      // Remplacement des namespaces dont le répertoire ne concorde pas :
  8.        if($classname[0] == 'MyApp')
  9.           $classname[0] == 'core';
 10.       elseif($classname[0] == 'Db')
 11.         $classname[0] == 'dblayer';
 12.       if($classname[0] == 'Easing')
 13.         $classname[0] == 'libs';
 14.       
 15.        $path = SOURCES_DIR.'/';
 16.        for($i = 0, $j = sizeof($classname)-1; $i < $j; ++$i)
 17.           $path .= strtolower($classname).'/';
 18.        $path .= 'class.'.array_pop($classname).'.php';
 19.       
 20.       if(file_exists($path))
 21.          require $path;
 22.     }
 23.       
 24.     spl_autoload_register('myapp_autoload');
 25.     if(function_exists('__autoload'))
 26.     spl_autoload_register('__autoload');
 27.     spl_autoload_register('spl_autoload');

Ici, on retiendra l'organisation des fichiers suivante : myproject/sources/core/class.Request.php, myproject/sources/view/class.Templates.php, etc.

L'utilisation du test sur l'existance du fichier avec file_exists() pourrait être évitée (et faire économiser du temps) si on s'assure qu'il n'est pas nécessaire de définir d'autre méthode de chargement automatique exécutée si celle-ci échoue, ou en inversant l'ordre d'exécution des différentes fonctions pour obtenir la plus efficace possible.

En plus, il est possible que la fonction myapp_autoload() ne soit plus modifiée, car si on souhaite créer un nouveau namespace et de nouvelles classes, on obtient automatiquement une correspondance, par exemple la classe Cookies dans le namespace Tools\Http, dont le nom absolu sera Tools\Http\Cookies sera, par défaut, recherchée dans myproject/sources/tools/http/class.Cookies.php.