Frage

Wie die meisten Web-Entwickler in diesen Tagen, genieße ich gründlich die Vorteile von festen MVC-Architektur für Web-Anwendungen und Websites. Wenn MVC mit PHP zu tun, die automatische Laden offensichtlich in äußerst praktisch.

Ich bin ein Fan von spl_autoload_register über einfach eine einzelne __autoload() Funktion definieren, da dies offensichtlich ist flexibler, wenn Sie verschiedene Basismodule eingebaut, die jeweils ihren eigenen automatischen Laden verwenden. Allerdings habe ich mich noch nie groß über die Ladefunktionen, die ich schreibe. Sie beinhalten eine Menge von String-Überprüfung und Verzeichnis Scannen, um für mögliche Klassen aussehen zu laden.

Zum Beispiel, sagen wir mal ich eine App haben, die einen Basispfad als PATH_APP definiert ist, und eine einfache Struktur mit Verzeichnissen namens models, views und controllers. Ich verwende oft eine Namensstruktur, wodurch Dateien IndexView.php und IndexController.php innerhalb des entsprechenden Verzeichnisses benannt sind, und Modelle haben in der Regel keine besondere Regelung standardmäßig. Ich könnte eine Ladefunktion für diese Struktur wie diese haben, die mit spl_autoload_register registriert wird:

public function MVCLoader($class)
{
    if (file_exists(PATH_APP.'/models/'.$class.'.php')) {
        require_once(PATH_APP.'/models/'.$class.'.php');
        return true;
    }
    else if (strpos($class,'View') !== false) {
        if (file_exists(PATH_APP.'/views/'.$class.'.php')) {
            require_once(PATH_APP.'/views/'.$class.'.php');
            return true;
        }
    }
    else if (strpos($class,'Controller') !== false) {
        if (file_exists(PATH_APP.'/controllers/'.$class.'.php')) {
            require_once(PATH_APP.'/controllers/'.$class.'.php');
            return true;
        }
    }
    return false;
}

Wenn es danach nicht gefunden hat, könnte ich eine andere Funktion hat Unterverzeichnisse in den Modellen Verzeichnis zu scannen. Doch all die if / else-ing, prüfter String und Verzeichnis Scannen scheint ineffizient zu mir, und ich möchte es verbessern.

Ich bin sehr gespannt, welche Dateibenennung und die automatische Laden von Strategien andere Entwickler beschäftigen könnten. Ich bin auf der Suche speziell für gute Techniken für eine effizienten automatischen Laden zu verwenden, und nicht Alternativen zu autoloading.

War es hilfreich?

Lösung

Dies ist, was ich habe in all meinen Projekten (hob direkt von der Quelle der letzten) mit:

public static function loadClass($class)
{
    $files = array(
        $class . '.php',
        str_replace('_', '/', $class) . '.php',
    );
    foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $base_path)
    {
        foreach ($files as $file)
        {
            $path = "$base_path/$file";
            if (file_exists($path) && is_readable($path))
            {
                include_once $path;
                return;
            }
        }
    }
}

Wenn ich für SomeClass_SeperatedWith_Underscores aussehen es für SomeClass_SeperatedWith_Underscores.php aussehen wird, gefolgt von Someclass / SeperatedWith / Underscores.php an jedem Verzeichnis wurzelt im aktuellen Suchpfad.

EDIT: Ich wollte nur da draußen setzen, dass ich dies in der Entwicklung für Effizienz nutzen und nicht unbedingt Zeit zu verarbeiten. Wenn Sie PEAR auf Ihrem Weg haben dann mit diesem können Sie nur die Klassen verwenden und müssen sie nicht enthalten, wenn Sie sie benötigen.

Ich neige dazu, meine Klassen in einer Hierarchie von Verzeichnissen zu halten, mit Unterstreichen Namespaces Zerschlagung ... Mit diesem Code können Sie mir die Dateistruktur schön und sauber halten, wenn ich will, oder eine schnelle Klassendatei ohne verschachtelte Verzeichnisse, wenn ich zu injizieren möchten (für das Hinzufügen einer einzigen Klasse oder zwei zu einer Bibliothek, die es Beklagte ist, aber nicht Teil des Projekts zur Zeit arbeite ich an).

Andere Tipps

Ich landete auf dieser Lösung:

Ich habe ein einziges Skript, das meine Klassenbibliothek Ordner durchläuft (die Unterordner für separate Module / Systeme enthält), und analysiert die Dateiinhalte für Klassendefinitionen suchen. Wenn es eine Klassendefinition in einer PHP-Datei (ziemlich einfach RegexMuster) findet, erstellt es einen symbolischen Link:

class_name.php -> actual/source/file.php

Auf diese Weise können Sie mir eine einzige, einfache Autoload-Funktion verwenden, die nur die Klassennamen muss und den Pfad zum Haupt Symlink-Ordner, und hat keinen Pfad / String-Manipulation zu tun.

Der beste Teil ist, dass ich völlig meine Quellcode neu anordnen oder ein neues Subsystem hinzufügen und einfach den Link Erzeugungs Skript ausführen alles automatisch geladen haben.

Wenn Sie möchten, Effizienz, dann sollten Sie nicht die Autostart-Funktion überhaupt werden. Autostart-Funktion ist für faul. Sie sollten einen expliziten Pfad zur Verfügung stellen, um Ihre Dateien enthalten, wenn Sie sie schließen. Wenn Ihr Autoload-Funktion diese Dateien finden können, dann können Sie kodieren sie explizit zu finden. Wenn Sie auf der Ansicht Teil des Codes arbeiten und über eine neue Sicht Klasse zu laden, durch die Autoload-Funktion umgehen lassen, nimmt erste Klasse eine Modellklasse ist? Das ist ineffizient. Stattdessen Ihr Code sollte nur sein:

include_once $this->views_path . $class . '.php';

Wenn Sie mehr „Ansicht“ Pfade benötigen, eine Funktion machen, die Ansichten lädt:

public function load_view($class) {
    // perhaps there's a mapping here instead....
    foreach ($this->views_paths as $path) {
        $filename = $path . $class . '.php';
        if (file_exists($filename)) {
            include_once $filename;
        }
    }
    throw ....
}

In jedem Fall an dem Punkt, wo die Anweisung steht, haben Sie die größten / genaueste Informationen über die Klasse, die Sie laden mögen. dass die Informationen über die Klasse vollständig zu laden, ist die einzige effiziente Klasse Ladestrategie. Ja, Sie können mit mehr Klassenvariablen oder (Gott bewahre) einige globale Variablen am Ende. Aber das ist ein besserer Kompromiss als nur faul und Scan-Teile des Dateisystems für Ihre Klasse zu sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top