PHP Espacement des noms et chargement automatique


Exemple

Techniquement, le chargement automatique fonctionne en exécutant un rappel lorsqu'une classe PHP est requise mais non trouvée. De tels rappels tentent généralement de charger ces classes.

En général, l'autoloading peut être compris comme une tentative de chargement de fichiers PHP (en particulier des fichiers de classe PHP, où un fichier source PHP est dédié à une classe spécifique) à partir des chemins appropriés selon le nom complet de la classe lorsqu'une classe est nécessaire .

Supposons que nous ayons ces classes:

Fichier de classe pour application\controllers\Base :

<?php
namespace application\controllers { class Base {...} }

Fichier de classe pour application\controllers\Control :

<?php
namespace application\controllers { class Control {...} }

Fichier de classe pour application\models\Page :

<?php
namespace application\models { class Page {...} }

Sous le dossier source, ces classes doivent être placées sur les chemins en tant que leurs noms de domaine complets respectivement:

  • Dossier d'origine
    • applications
      • controllers
        • Base.php
        • Control.php
      • models
        • Page.php

Cette approche permet de résoudre par programmation le chemin du fichier de classe en fonction du FQN, en utilisant cette fonction:

function getClassPath(string $sourceFolder, string $className, string $extension = ".php") {
    return $sourceFolder . "/" . str_replace("\\", "/", $className) . $extension; // note that "/" works as a directory separator even on Windows
}

La fonction spl_autoload_register nous permet de charger une classe en cas de besoin en utilisant une fonction définie par l'utilisateur:

const SOURCE_FOLDER = __DIR__ . "/src";
spl_autoload_register(function (string $className) {
    $file = getClassPath(SOURCE_FOLDER, $className);
    if (is_readable($file)) require_once $file;
});

Cette fonction peut être étendue pour utiliser des méthodes de chargement de secours:

const SOURCE_FOLDERS = [__DIR__ . "/src", "/root/src"]);
spl_autoload_register(function (string $className) {
    foreach(SOURCE_FOLDERS as $folder) {
        $extensions = [
            // do we have src/Foo/Bar.php5_int64?
            ".php" . PHP_MAJOR_VERSION . "_int" . (PHP_INT_SIZE * 8),
            // do we have src/Foo/Bar.php7?
            ".php" . PHP_MAJOR_VERSION,
            // do we have src/Foo/Bar.php_int64?
            ".php" . "_int" . (PHP_INT_SIZE * 8),
            // do we have src/Foo/Bar.phps?
            ".phps"
            // do we have src/Foo/Bar.php?
            ".php"
        ];
        foreach($extensions as $ext) {
            $path = getClassPath($folder, $className, $extension);
            if(is_readable($path)) return $path;
        }
    }
});

Notez que PHP ne tente pas de charger les classes à chaque fois qu'un fichier utilisant cette classe est chargé. Il peut être chargé au milieu d'un script, ou même dans des fonctions d'arrêt. C'est l'une des raisons pour lesquelles les développeurs, en particulier ceux qui utilisent l'autoloading, devraient éviter de remplacer les fichiers source en cours d'exécution dans le runtime, notamment dans les fichiers phar.