Frage

Ich versuche, zu nutzen in PHP von selbstladende. Ich habe verschiedene Klassen in verschiedenen Verzeichnissen, und so habe ich das automatische Laden von Bootstrap haben sich wie folgt:

function autoload_services($class_name)
{
    $file = 'services/' . $class_name. '.php';
    if (file_exists($file))
    {
        require_once($file);
    }
}

function autoload_vos($class_name)
{
    $file = 'vos/' . $class_name. '.php';
    if (file_exists($file))
    {
        require_once($file);
    }
}

function autoload_printers($class_name)
{
    $file = 'printers' . $class_name. '.php';
    if (file_exists($file))
    {
        require_once($file);
    }
}

spl_autoload_register('autoload_services');
spl_autoload_register('autoload_vos');
spl_autoload_register('autoload_printers');

Es scheint alles zu funktionieren, aber ich gerade zu überprüfen wollte, dass dies tatsächlich akzeptable Praxis betrachtet wird.

War es hilfreich?

Lösung

Sicher, sieht gut aus. Das einzige, was man tun könnte, ist sie in der Reihenfolge registriert sie sind am ehesten zu schlagen. Zum Beispiel, wenn Sie Ihre am häufigsten verwendeten Klassen in Dienstleistungen sind, dann vos, dann Drucker, die Reihenfolge Sie haben, ist perfekt. Dies ist, weil sie eine Warteschlange eingereiht und in der richtigen Reihenfolge aufgerufen, so dass Sie, indem Sie diese etwas bessere Leistung erzielen werden.

Andere Tipps

Sie können verwendet werden:

set_include_path(implode(PATH_SEPARATOR, array(get_include_path(), './services', './vos', './printers')));
spl_autoload_register();

Mit spl_autoload_register ohne Argumente wird registrieren spl_autoload , die für den Klassennamen in den Verzeichnissen der include path . Beachten Sie, dass diese die Klassennamen für sie vor der Suche im Dateisystem klein geschrieben werden.

Es ist in Ordnung, aber wenn dies sind nur Ordner unter einem bestimmten Ordner, z.

/library
    /JonoB
        /services
        /vos
        /printers

Sie können das Hinzufügen diese zu Ihrem Klassennamen betrachten möchten, z.

JonoB_Services_Foo, JonoB_Vos_Bar, JonoB_Printers_Baz

und teilt dann die $classname durch den Unterstrich und nimmt jeden Teil als Ordnernamen. Dies ist vergleichbar mit PEAR Klassennamen Konvention . Auf diese Weise würden Sie nur einen Lader haben.

Statt PEAR-Konvention Stil Klassennamen, können Sie auch Namespace ( Autoload Beispiel ), aber bewusst sein, dass diese erfordern PHP5.3, die auf Shared-Hosting noch nicht weit verbreitet ist. Und Ihre Anwendung wird nicht rückwärts kompatibel sein mit PHP <5.3 dann (wenn das ein Problem).

Good advice from all the other answers.

Let me add that each autoloader should first check if it even cares about the class being passed in, and return immediately if not.

So if you do as Gordon suggests and add a prefix to each class, then for Services_Foo the autoloader autoload_services() should see if "Services_" is the first substring of $class_name, and if not return false immediately to save on any further processing, especially filesystem checks.

If i was supposed to refactor your code, it would be

function custom_autoload($class_name){
        $dirs = array('services','vos','printers') 
        foreach($dirs as $dir){ 
            $file = $dir.'/'.$class_name. '.php';
            if (file_exists($file)){
               require $file;
               break; // if i have maintained naming conventions as per dir as there
                  // is no point for looking eg: sample1_printer.php in the vos/ 
                 // or printer/. this way iam avoiding unnecessary loop
             }
        }
 }
    spl_autoload_register('custom_autoload');    

I have written my own ClassLoader using spl_autoload_register.
The advantage is that the function looks in every subfolder starting in the current folder.
I simply include this file in every PHP file and never have to worry about any include/require directive.
It simply works :-)

<?php
spl_autoload_register('AutoLoadClasses');

/************************************************************************************
 * AutoLoadClasses
 *
 * Diese Funktion lädt Klassen in gleichnamigen Dateien bei Bedarf automatisch nach,
 * sobald eine (bis dahin unbekannte) Klasse erstmalig instanziert wird.
 * $var = new MeineKlasse; => Es wird nach der Datei class_MeineKlasse.php gesucht
 * Die Suche erfolgt rekursiv in allen Unterordnern ausgehend von dem Ordner, in dem
 * das aufrufende PHP-Script liegt.
 *
 * Michael Hutter / Dezember 2017
 */
function AutoLoadClasses($Klassenname, $StartOrdner = null)
{
    if (is_null($StartOrdner))
    {
        $StartOrdner = __DIR__; # Ausgangspunkt für die Suche: Ordner, in dem sich das aufrufende PHP-Script befindet
        $StartInstanz = true;
    }
    $ZielDateiname = "class_$Klassenname.php";
    $FileList = scandir($StartOrdner, 1); # Sortierung 1 => kommt schneller zum Ziel, falls Ordnernamen im allgemeinen mit einem Großbuchstaben beginnen
    foreach ($FileList as $file) # Alle Dateien und Ordner durchgehen
    {
        $Vollpfad = $StartOrdner.DIRECTORY_SEPARATOR.$file;
        if (is_dir($Vollpfad) && (substr($file, 0, 1) !== '.')) # Ordner?
        {
            #echo "Ordner $StartOrdner<br>";
            $result = AutoLoadClasses($Klassenname, $Vollpfad);
            if ($result) return; # Abbruch, falls Ziel gefunden
        }
        else if (preg_match('/\.php$/i' , $file)) # .php-Datei?
        {
            #echo "$file<br>";
            if ($file == $ZielDateiname) # Dateiname entspricht Klassenname?
            {
                include $Vollpfad;
                return true; # Abbruch aller Rekursionen, da Ziel gefunden
            }
        }
    }
    if (isset($StartInstanz))
        die("<table border bgcolor=red><tr><td>Fehler: Die Datei <b>$ZielDateiname</b> konnte in keinem der Unterordner gefunden werden!</td></tr></table>");
    return false;
}
?>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top