Chargement automatique de classes
Par CrazyCat le 18/02/2009, 11:47 - PHP - Lien permanent
Une des fonctionnalités innovante de PHP5 est l'ajout d'un système permettant de vérifier si une classe appelée est bien chargée, et si elle ne l'est pas, de tenter de l'inclure. Cela peut donc vous permettre, si vous êtes rigoureux dans votre développement (et surtout dans le nommage de vos fichiers), de ne pas inclure par défaut vos classes et de laisser le système s'en occuper lorsque c'est utile.
Pour ce faire, la fonction magique __autoload() vous permet de définir un mode de recherche et/ou chargement personnalisé.
Principe
Nous partirons du principe que les classes sont toutes dans les répertoires includes/classes/* (donc dans includes/classes/ ou un sous-répertoire) et que le nommage des fichiers est du type Class[NomDeLaClasse].php.
La fonction __autoload() devra donc analyser le répertoire et les sous-répertoires afin de vérifier si le fichier existe. Pour ce faire, nous utiliserons une seconde fonction (recursiveFolder()) qui fera le parcours récursif des répertoires.
Fonction __autoload()
Elle est très simple: elle lance la fonction de parcours des répertoires, et inclut le fichier s'il est trouvé.
<?php // Définition du répertoire initial define('CLASS_PATH', 'includes/classes/'); function __autoload($strClassName) { $strFolder = recursiveFolder($strClassName, CLASS_PATH); if($strFolder) { require_once($strFolder."class".$strClassName.".php"); } } ?>
Fonction recursiveFolder
Cette fonction renvoit le chemin d'accès à la classe si le fichier est trouvé, sinon elle renvoit false.
Le code n'est pas expliqué car il fera l'objet d'un autre billet concernant une classe plus globale sur le FileSystem.
function recursiveFolder($strClassName, $strPath, $strSub = "/") { $strPath .= $strSub; $strDir = dir($strPath); if (file_exists($strPath."class".$strClassName.".php")) { return $strPath; } while(false !== ($strFolder = $strDir->read())) { if ($strFolder == "." || $strFolder == "..") { continue; } if (is_dir($strPath.$strFolder)) { $strSubFolder = recursiveFolder($strClassName, $strPath.$strFolder); if ($strSubFolder) return $strSubFolder; } } $strDir->close(); return false; } ?>