PHP Chargement automatique


Exemple

Personne ne veut require ou include chaque fois qu'une classe ou un héritage est utilisé. Parce qu'il peut être douloureux et facile à oublier, PHP propose le chargement automatique. Si vous utilisez déjà Composer, lisez l'article sur le chargement automatique à l'aide de Composer .

Qu'est-ce que le chargement automatique?

Le nom dit tout. Vous n'avez pas à obtenir le fichier dans lequel la classe demandée est stockée, mais PHP le charge automatiquement.

Comment puis-je faire cela en PHP de base sans code tiers?

Il y a la fonction __autoload , mais il est préférable d'utiliser spl_autoload_register . Ces fonctions seront considérées par PHP chaque fois qu'une classe n'est pas définie dans l'espace donné. L'ajout de chargement automatique à un projet existant ne pose donc aucun problème, car les classes définies (via require ie) fonctionneront comme avant. Par souci de précision, les exemples suivants utiliseront des fonctions anonymes, si vous utilisez PHP <5.3, vous pouvez définir la fonction et transmettre son nom comme argument à spl_autoload_register .

Exemples

spl_autoload_register(function ($className) {
    $path = sprintf('%s.php', $className);
    if (file_exists($path)) {
        include $path;
    } else {
        // file not found
    }
});

Le code ci-dessus essaie simplement d'inclure un nom de fichier avec le nom de la classe et l'extension ".php" ajoutée à l'aide de sprintf . Si FooBar doit être chargé, il semble que FooBar.php existe et si oui, l'inclut.

Bien sûr, cela peut être étendu pour répondre aux besoins individuels du projet. Si _ dans un nom de classe est utilisé pour grouper, par exemple User_Post et User_Image deux font référence à User , les deux classes peuvent être conservées dans un dossier appelé "User" comme ceci:

spl_autoload_register(function ($className) {
    //                        replace _ by / or \ (depending on OS)
    $path = sprintf('%s.php', str_replace('_', DIRECTORY_SEPARATOR, $className) );
    if (file_exists($path)) {
        include $path;
    } else {
        // file not found
    }
});

La classe User_Post va maintenant être chargée depuis "User / Post.php", etc.

spl_autoload_register peut être adapté à divers besoins. Tous vos fichiers avec des classes sont nommés "class.CLASSNAME.php"? Aucun problème. Divers imbrication ( User_Post_Content => "User / Post / Content.php")? Pas de problème non plus.

Si vous voulez un mécanisme de chargement automatique plus élaboré et que vous ne voulez toujours pas inclure Composer, vous pouvez travailler sans ajouter de bibliothèques tierces.

spl_autoload_register(function ($className) {
    $path = sprintf('%1$s%2$s%3$s.php',
        // %1$s: get absolute path
        realpath(dirname(__FILE__)),
        // %2$s: / or \ (depending on OS)
        DIRECTORY_SEPARATOR,
        // %3$s: don't wory about caps or not when creating the files
        strtolower(
            // replace _ by / or \ (depending on OS)
            str_replace('_', DIRECTORY_SEPARATOR, $className)
        )
    );

    if (file_exists($path)) {
        include $path;
    } else {
        throw new Exception(
            sprintf('Class with name %1$s not found. Looked in %2$s.',
                $className,
                $path
            )
        );
    }
});

En utilisant des chargeurs automatiques comme celui-ci, vous pouvez écrire du code comme ceci:

require_once './autoload.php'; // where spl_autoload_register is defined

$foo = new Foo_Bar(new Hello_World());

Utiliser des classes:

class Foo_Bar extends Foo {}
class Hello_World implements Demo_Classes {}

Ces exemples seront des classes include de foo/bar.php , foo.php , hello/world.php et demo/classes.php .