PHP
Autoloading Primer
Suche…
Syntax
- benötigen
- spl_autoload_require
Bemerkungen
Durch das automatische Laden als Teil einer Rahmenstrategie wird die Menge an Boilerplate-Code, den Sie schreiben müssen, vereinfacht.
Inline-Klassendefinition, kein Laden erforderlich
// zoo.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
$animal = new Animal();
$animal->eats('meat');
PHP weiß, was Animal
ist, bevor es new Animal
ausführt, da PHP Quelldateien von oben nach unten liest. Was aber, wenn wir an vielen Stellen neue Tiere erstellen wollten, nicht nur in der Quelldatei, in der sie definiert wurden? Dazu müssen wir die Klassendefinition laden .
Manuelles Klassenladen mit Anfordern
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// zoo.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('slop');
// aquarium.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('shrimp');
Hier haben wir drei Dateien. Eine Datei ("Animal.php") definiert die Klasse. Diese Datei hat keine Nebeneffekte außer der Definition der Klasse und hält das Wissen über ein "Tier" an einem Ort. Es ist leicht versionierbar. Es ist leicht wiederverwendbar.
Zwei Dateien verbrauchen die „Animal.php“ Datei manuell require
die Datei -Ing. Wieder liest PHP Quelldateien von oben nach unten, so dass die Anforderung die Datei "Animal.php" findet und die Definition der Klasse Animal
vor dem Aufruf von new Animal
verfügbar macht.
Nun stellen wir uns vor, wir hätten Dutzende oder Hunderte von Fällen gehabt, in denen wir new Animal
durchführen wollten. Das würde (Wortspiel) require
, viele, viele require
Anweisungen, die für den Code sehr langwierig sind.
Autoloading ersetzt das manuelle Laden von Klassendefinitionen
// autoload.php
spl_autoload_register(function ($class) {
require_once "$class.php";
});
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// zoo.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('slop');
// aquarium.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('shrimp');
Vergleichen Sie dies mit den anderen Beispielen. Beachten Sie, wie require "Animal.php"
ersetzt wurde durch require "autoload.php"
. Wir fügen zur Laufzeit noch eine externe Datei hinzu, aber anstatt eine spezifische Klassendefinition aufzunehmen, enthalten wir eine Logik, die jede Klasse enthalten kann. Es ist eine Ebene der Indirektion, die unsere Entwicklung erleichtert. Statt eines Schreibens require
für jede Klasse , die wir benötigen, schreiben wir ein require
für alle Klassen. Wir können ersetzen N require
mit 1 require
.
Die Magie geschieht mit spl_autoload_register . Diese PHP - Funktion nimmt einen Verschluss und fügt den Verschluß zu einer Warteschlange von Verschlüssen. Wenn PHP auf eine Klasse stößt, für die es keine Definition gibt, übergibt PHP den Klassennamen an jeden Abschluss in der Warteschlange. Wenn die Klasse nach dem Aufrufen einer Schließung vorhanden ist, kehrt PHP zum vorherigen Geschäft zurück. Wenn die Klasse nach dem Ausprobieren der gesamten Warteschlange nicht vorhanden ist, stürzt PHP mit "Class 'Whatever" nicht gefunden ab. "
Autoloading als Teil einer Framework-Lösung
// autoload.php
spl_autoload_register(function ($class) {
require_once "$class.php";
});
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// Ruminant.php
class Ruminant extends Animal {
public function eats($food) {
if ('grass' === $food) {
parent::eats($food);
} else {
echo "Yuck, $food!";
}
}
}
// Cow.php
class Cow extends Ruminant {
}
// pasture.php
require 'autoload.php';
$animal = new Cow;
$animal->eats('grass');
Dank unseres generischen Autoloaders haben wir Zugriff auf alle Klassen, die unserer Namenskonvention für Autoloader entsprechen. In diesem Beispiel ist unsere Konvention einfach: Die gewünschte Klasse muss eine Datei in demselben Verzeichnis haben, die nach der Klasse benannt ist und auf ".php" endet. Beachten Sie, dass der Klassenname genau mit dem Dateinamen übereinstimmt.
Ohne die automatischen Laden, würden wir müssen manuell require
Basisklassen. Wenn wir einen ganzen Zoo mit Tieren bauen würden, hätten wir Tausende von Anforderungsaussagen, die leichter durch einen einzelnen Autoloader ersetzt werden könnten.
Letztendlich ist PHP-Autoloading ein Mechanismus, mit dem Sie weniger mechanischen Code schreiben können, sodass Sie sich auf die Lösung geschäftlicher Probleme konzentrieren können. Alles, was Sie tun müssen, ist eine Strategie zu definieren, die den Klassennamen dem Dateinamen zuordnet . Sie können Ihre eigene Autoloading-Strategie wie hier beschrieben ausführen. Sie können auch einen der Standard-Standards verwenden, die von der PHP-Community übernommen wurden: PSR-0 oder PSR-4 . Mit Composer können Sie diese Abhängigkeiten generisch definieren und verwalten.
Autoloading mit Composer
Composer generiert eine vendor/autoload.php
Datei.
Vielleicht fügen Sie diese Datei einfach hinzu und Sie erhalten das automatische Laden kostenlos.
require __DIR__ . '/vendor/autoload.php';
Dies macht die Arbeit mit Abhängigkeiten von Drittanbietern sehr einfach.
Sie können auch Ihren eigenen Code zum Autoloader hinzufügen, indem Sie Ihrem composer.json
einen Autoload-Abschnitt hinzufügen.
{
"autoload": {
"psr-4": {"YourApplicationNamespace\\": "src/"}
}
}
In diesem Abschnitt definieren Sie die Autoload-Zuordnungen. In diesem Beispiel ist es eine PSR-4- Zuordnung eines Namespaces zu einem Verzeichnis: Das Verzeichnis /src
befindet sich im Stammordner Ihres Projekts auf derselben Ebene wie das Verzeichnis /vendor
. Ein Beispiel-Dateiname wäre src/Foo.php
, der eine YourApplicationNamespace\Foo
Klasse enthält.
Wichtig: Nachdem Sie dem Autoload-Abschnitt neue Einträge hinzugefügt haben, müssen Sie den Befehl dump-autoload
erneut ausführen, um die Datei vendor/autoload.php
mit den neuen Informationen neu zu generieren und zu aktualisieren.
Zusätzlich zum classmap
von PSR-4
unterstützt Composer auch PSR-0
, classmap
und das classmap
files
. Weitere Informationen finden Sie in der Referenz zum automatischen Laden .
Wenn Sie die Datei /vendor/autoload.php
, wird eine Instanz des Composer Autoloader zurückgegeben. Sie können den Rückgabewert des Include-Aufrufs in einer Variablen speichern und weitere Namespaces hinzufügen. Dies kann beispielsweise für das automatische Laden von Klassen in einer Testsuite hilfreich sein.
$loader = require __DIR__ . '/vendor/autoload.php';
$loader->add('Application\\Test\\', __DIR__);