it-swarm.com.de

PHP spl_autoload_register

Ich versuche, das Autoloading in PHP zu nutzen. Ich habe verschiedene Klassen in verschiedenen Verzeichnissen, und daher habe ich das Autoloading wie folgt gebootet:

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 gut zu funktionieren, aber ich wollte nur noch einmal prüfen, ob dies tatsächlich als akzeptable Praxis angesehen wird.

30
JonoB

Sicher, sieht gut aus. Sie können sie nur in der Reihenfolge registrieren, in der sie am wahrscheinlichsten treffen. Wenn sich beispielsweise Ihre am häufigsten verwendeten Klassen in Diensten befinden, dann sind vos und Drucker die Reihenfolge, die Sie haben, perfekt. Dies liegt daran, dass sie sich in der Warteschlange befinden und in der Reihenfolge aufgerufen werden. Dadurch erzielen Sie eine etwas bessere Leistung.

32
mr. w

Du könntest benutzen:

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

Wenn Sie spl_autoload_register ohne Argumente verwenden, wird das Register spl_autoload registriert, das in den Verzeichnissen der include path nach dem Klassennamen sucht. Beachten Sie, dass der Klassenname vor der Suche im Dateisystem in Kleinbuchstaben geschrieben wird.

19
NikiC

Es ist in Ordnung, aber wenn dies nur Ordner unterhalb eines bestimmten Ordners sind, z.

/library
    /JonoB
        /services
        /vos
        /printers

sie möchten vielleicht erwägen, diese zu Ihren Klassennamen hinzuzufügen, z.

JonoB_Services_Foo, JonoB_Vos_Bar, JonoB_Printers_Baz

teilen Sie dann den $classname durch den Unterstrich auf und übernehmen Sie jeden Teil als Ordnernamen. Dies ist vergleichbar mit PEAR Klassennamenkonvention . Auf diese Weise hätten Sie nur einen Lader.

Anstelle von PEAR konventionellen Klassennamen können Sie auch namespaces ( autoload example ) verwenden. Beachten Sie jedoch, dass PHP5.3 erforderlich ist, das bei Shared Hosting noch nicht weit verbreitet ist. Und dann ist Ihre Anwendung nicht rückwärtskompatibel mit PHP <5.3 (falls dies ein Problem ist).

4
Gordon

Guter Rat von allen anderen Antworten. 

Lassen Sie mich hinzufügen, dass jeder Autoloader zuerst prüfen sollte, ob er sich überhaupt für die übergebene Klasse interessiert, und ihn sofort zurückschickt, wenn nicht.

Wenn Sie also wie von Gordon vorgeschlagen vorgehen und jeder Klasse ein Präfix hinzufügen, sollte der Autoloader autoload_services() für Services_Foo sehen, ob "Services_" der erste Teilstring von $class_name ist. Wenn nicht, geben Sie sofort false zurück, um weitere Verarbeitungsschritte zu speichern, insbesondere Dateisystemprüfungen .

3
Fanis

Wenn ichrefactor your codehätte, wäre es das

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');    
2
Angelin Nadar

Ich habe meinen eigenen ClassLoader mit spl_autoload_register geschrieben.
Der Vorteil besteht darin, dass die Funktion in jedem Unterordner beginnt, der im aktuellen Ordner beginnt.
Ich füge diese Datei einfach in jede PHP -Datei ein und muss mich nie um eine Include/Require-Anweisung kümmern.
Es funktioniert einfach :-)

<?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;
}
?>
0
Michael Hutter