Dieser Artikel ist eine Zusammenfassung der automatischen Ladefunktion von PHP und behandelt die automatische Ladefunktion von PHP, den PHP-Namespace, die PSR0- und PSR4-Standards von PHP usw.
1. Automatische Ladefunktion von PHP
Der Ursprung der automatischen Ladefunktion von PHP
Wenn Sie während des PHP-Entwicklungsprozesses eine Klasse von außen einführen möchten, verwenden Sie normalerweise die Methoden include und require, um die Datei einzubinden, die die Klasse definiert. Wenn dies im kleinen Maßstab entwickelt wird, gibt es kein großes Problem. In großen Entwicklungsprojekten bringt die Verwendung dieser Methode jedoch einige versteckte Probleme mit sich: Wenn eine PHP-Datei viele andere Klassen verwenden muss, sind viele Require/Include-Anweisungen erforderlich, was zu Auslassungen oder Einschlüssen unnötiger Klassendateien führen kann . Wenn eine große Anzahl von Dateien die Verwendung anderer Klassen erfordert, ist es ein Albtraum, sicherzustellen, dass jede Datei die richtige Klassendatei enthält, und require_once ist teuer.
PHP5 bietet eine Lösung für dieses Problem, nämlich den Autoload-Mechanismus von Klassen. Der Autoload-Mechanismus ermöglicht es PHP-Programmen, Klassendateien nur dann automatisch einzubinden, wenn Klassen verwendet werden, anstatt alle Klassendateien zu Beginn einzubinden. Dieser Mechanismus wird auch als Lazy Loading bezeichnet.
Zusammenfassend lässt sich sagen, dass die automatische Ladefunktion mehrere Vorteile mit sich bringt:
Sie müssen die nicht verwenden Klasse vor „include“ oder „require“
erfordert/include nur Dateien, wenn Klassen verwendet werden, was verzögertes Laden implementiert und das Erfordernis/include redundanter Dateien vermeidet.
Es besteht keine Notwendigkeit, die tatsächliche Festplattenadresse der eingeführten Klasse zu berücksichtigen, um die Trennung von logischen und physischen Dateien zu realisieren.
Wenn Sie mehr über die automatische Ladefunktion im Detail erfahren möchten, können Sie die Informationen einsehen:
Automatischer Klassenlademechanismus von PHP
Implementierungsanalyse des automatischen Lademechanismus von PHP
Normalerweise führt PHP5 bei Verwendung einer Klasse automatisch die Funktion _autoload() aus Von uns im Programm angepasst, können wir die Klassen laden, die wir verwenden müssen. Das Folgende ist ein einfaches Beispiel:
<span style="font-size: 16px;">function __autoload($classname) { <br> require_once ($classname . "class.php"); <br>}<br></span>
In unserem einfachen Beispiel fügen wir den Klassennamen direkt zur Erweiterung „.class.php“ hinzu, um den Klassendateinamen zu bilden Verwenden Sie require_once, um es zu laden. Aus diesem Beispiel können wir ersehen, dass Autoload mindestens drei Dinge tun muss:
Bestimmen Sie den Klassendateinamen basierend auf dem Klassennamen
Bestimmen Sie den Festplattenpfad, in dem sich die Klassendateien befinden (in unserem Fall befinden sich die Klassen im einfachsten Fall im selben Ordner wie die PHP-Programmdateien). Rufen Sie sie auf);
Lädt Klassen aus Festplattendateien in das System.
Der dritte Schritt ist der einfachste, verwenden Sie einfach include/require. Um die Funktionen des ersten und zweiten Schritts zu realisieren, muss während der Entwicklung die Zuordnungsmethode zwischen dem Klassennamen und der Festplattendatei vereinbart werden. Nur so können wir die entsprechende Festplattendatei anhand des Klassennamens finden.
Wenn eine große Anzahl von Klassendateien einbezogen werden muss, müssen wir nur die entsprechenden Regeln ermitteln und dann in der Funktion __autoload() den Klassennamen mit dem tatsächlichen abgleichen Festplattendatei, Sie können den Effekt des verzögerten Ladens erzielen. Hier können wir auch erkennen, dass das Wichtigste bei der Implementierung der Funktion _autoload() die Implementierung der Zuordnungsregeln zwischen dem Klassennamen und der tatsächlichen Festplattendatei ist.
Wenn Sie bei der Implementierung eines Systems viele andere Klassenbibliotheken verwenden müssen, sind diese Klassenbibliotheken können von verschiedenen Entwicklern geschrieben sein und unterschiedliche Zuordnungsregeln zwischen Klassennamen und tatsächlichen Festplattendateien haben. Wenn Sie zu diesem Zeitpunkt das automatische Laden von Klassenbibliotheksdateien implementieren möchten, müssen Sie alle Zuordnungsregeln in der Funktion __autoload() implementieren. In diesem Fall ist die Implementierung der Funktion autoload() möglicherweise sehr kompliziert oder sogar unmöglich. Am Ende kann die Funktion autoload() sehr aufgebläht werden. Selbst wenn sie implementiert werden kann, wird sie sich stark negativ auf die zukünftige Wartung und Systemeffizienz auswirken.
Wo liegt also das Problem? Das Problem besteht darin, dass _autoload() eine globale Funktion ist, die nur einmal definiert werden kann und nicht flexibel genug ist. Daher müssen alle logischen Regeln, die Klassennamen und Dateinamen entsprechen, in einer Funktion implementiert werden, was dazu führt, dass diese Funktion aufgebläht wird. Wie kann man dieses Problem lösen? Die Antwort besteht darin, einen _autoload-Aufrufstapel zu verwenden, verschiedene Zuordnungsbeziehungen in verschiedene _autoload-Funktionen zu schreiben und diese dann einheitlich zu registrieren und zu verwalten. Dies ist das in PHP5 eingeführte SPL-Autoload.
SPL ist die Abkürzung für Standard PHP Library. Es handelt sich um eine in PHP5 eingeführte Erweiterungsbibliothek. Zu ihren Hauptfunktionen gehört die Implementierung des Autoload-Mechanismus und verschiedener Iterator-Schnittstellen oder -Klassen. SPL Autoload hat mehrere spezifische Funktionen:
spl_autoload_register: Registrieren Sie die __autoload()-Funktion
spl_autoload_unregister: Registrierung registrierter Funktionen aufheben
spl_autoload_functions: Alle registrierten Funktionen zurückgeben
spl_autoload_call: Probieren Sie alle registrierten Funktionen aus, um eine Klasse zu laden
spl_autoload: Standardimplementierung von __autoload()
spl_autoload_extensions: Registrieren Sie die von der spl_autoload-Funktion verwendeten Standarddateierweiterungen und geben Sie sie zurück.
Die detaillierte Verwendung dieser Funktionen finden Sie in der ausführlichen Erklärung von spl_autoload in PHP
Einfach gesagt, spl_autoload ist SPL selbst. Die Definition der Funktion __autoload() ist sehr einfach. Sie besteht darin, in das registrierte Verzeichnis (festgelegt durch set_include_path) zu gehen, um die .php/.inc-Datei mit demselben Namen wie $classname zu finden. Natürlich können Sie durch die Registrierung von Erweiterungen (spl_autoload_exionsions) auch bestimmte Dateitypen angeben.
Und spl_autoload_register() ist der oben erwähnte Autoload-Aufrufstapel. Wir können mehrere unserer eigenen _autoload()-Funktionen für diese Funktion registrieren. Wenn PHP den Klassennamen nicht finden kann ruft diesen Stapel auf und ruft nacheinander die benutzerdefinierte Funktion _autoload () auf, um die automatische Ladefunktion zu realisieren. Wenn wir in diese Funktion keine Parameter eingeben, wird die Funktion spl_autoload() registriert.
Okay, das ist die unterste Ebene des automatischen Ladens von PHP. Der Registrierungsmechanismus ist bereits sehr flexibel, aber was fehlt? Wie oben erwähnt, ist der Schlüssel zum automatischen Laden die Zuordnung von Klassennamen und Dateien. Diese Zuordnungsbeziehung ist sehr flexibel, aber wenn sie zu flexibel ist, wirkt sie etwas chaotisch Spezifikation für diese Zuordnungsbeziehung, die im Standard PSR PSR0 und PSR4 ist.
Aber bevor wir über PSR0 und PSR4 sprechen, müssen wir auch das Problem des PHP-Namespace verstehen, da diese beiden Standards eigentlich nicht auf die Zuordnung von Klassennamen und Verzeichnisdateien abzielen, sondern Ist die Zuordnung von Namespaces und Dateien. Warum passiert das? Nach meinem Verständnis ist der Namespace gewissermaßen ein Alias des Klassennamens, also warum sollten wir den Namespace einführen und welche Vorteile hat der Namespace? 🎜>
2. NamespaceUm den Namespace zu verstehen, werfen Sie zunächst einen Blick auf die Einführung des Namespace in der offiziellen Dokumentation:
Was ist ein Namespace? Im Großen und Ganzen ist ein Namespace eine Möglichkeit, Dinge zu kapseln. Dieses abstrakte Konzept findet sich vielerorts. Verzeichnisse werden beispielsweise in Betriebssystemen verwendet, um zusammengehörige Dateien zu gruppieren, und sie fungieren als Namespaces für die Dateien im Verzeichnis. Beispielsweise kann die Datei foo.txt gleichzeitig in den Verzeichnissen /home/greg und /home/other vorhanden sein, zwei foo.txt-Dateien können jedoch nicht im selben Verzeichnis vorhanden sein. Darüber hinaus müssen wir beim Zugriff auf die foo.txt-Datei außerhalb des Verzeichnisses /home/greg den Verzeichnisnamen und das Verzeichnistrennzeichen vor den Dateinamen setzen, um /home/greg/foo.txt zu erhalten. Die Anwendung dieses Prinzips auf den Bereich der Programmierung ist das Konzept des Namespace.
In PHP werden Namespaces verwendet, um zwei Arten von Problemen zu lösen, die beim Erstellen von wiederverwendbarem Code wie Klassen oder Funktionen beim Schreiben von Klassenbibliotheken oder Anwendungen auftreten:
1 Vom Benutzer geschriebener Code und PHP-interne Klassen Namenskonflikte zwischen /functions/ Konstanten oder Klassen/Funktionen/Konstanten von Drittanbietern
2 Erstellen Sie einen (oder kurzen) Namen für einen sehr langen Bezeichnernamen (normalerweise definiert, um die erste Art von Problem zu lindern), und verbessern Sie die Lesbarkeit des Quellcodes.
PHP-Namespaces bieten eine Möglichkeit, verwandte Klassen, Funktionen und Konstanten zu gruppieren.
Um es einfach auszudrücken: PHP erlaubt keine zwei Klassen, Funktionen oder Variablennamen mit demselben Namen im Programm, daher sind einige Leute sehr verwirrt Ist es in Ordnung, wenn Sie nicht denselben Namen haben? Tatsächlich sind viele große Programme auf viele Bibliotheken von Drittanbietern angewiesen. Dies ist das erste Problem auf der offiziellen Website. Wie kann man dieses Problem lösen? Wenn kein Namespace vorhanden ist, kann der arme Programmierer nur den Klassennamen a_b_c_d_e_f angeben, wobei a/b/c/d/e/f im Allgemeinen eine eigene spezifische Bedeutung hat, sodass im Allgemeinen keine Konflikte auftreten, sondern lange Klassennamen sind ermüdend beim Schreiben und noch unangenehmer beim Lesen. Daher hat PHP5 den Klassennamen eingeführt, und der Namespace ist der Namespace. Beim Schreiben/Lesen des Programms wird der Klassenname direkt verwendet, wodurch das Problem gelöst wird.
Darüber hinaus bieten Namespaces eine Möglichkeit, verwandte Klassen, Funktionen und Konstanten zu gruppieren. Dies ist auch eine großartige Verwendung von objektorientierten Sprachnamensräumen. Klassen, Variablen und Funktionen, die für bestimmte Zwecke erforderlich sind, werden in einen Namensraum geschrieben und gekapselt.
Nachdem wir das Problem der Klassennamen gelöst haben, können wir endlich zum PSR-Standard zurückkehren. Wie standardisieren PSR0 und PSR4 also die Zuordnungsbeziehung zwischen Dateien und Namespaces? Die Antwort lautet: Einschränkungen bei der Benennung des Namespace (naja, es ist etwas verwirrend), dem Speicherort des Klassendateiverzeichnisses und der Zuordnungsbeziehung zwischen den beiden. Dies ist der Kern des Standards. Eine ausführlichere Beschreibung finden Sie in Modern PHP New Feature Series (1) – Namespace
3. PSR Standard
Bevor wir über PSR0 und PSR4 sprechen, stellen wir den PSR-Standard vor. Der Erfinder und Standardisierer des PSR-Standards ist: PHP-FIG, und seine Website ist: www.php-fig.org. Es war dieses Konsortium, das die PSR-Spezifikation erfunden und erstellt hat. FIG ist die Abkürzung für Framework Interoperability Group. Sie wurde 2009 von mehreren Open-Source-Framework-Entwicklern gegründet. Obwohl es sich nicht um eine „offizielle“ Organisation handelt, repräsentiert sie auch einen großen Teil der Community . Der Zweck der Organisation besteht darin, die Codierungsstandards jedes Projekts mit den geringsten Einschränkungen zu vereinheitlichen, um zu vermeiden, dass der eigene Entwicklungsstil jedes Unternehmens die Entwicklung von Programmdesignern behindert. Daher hat jeder PSR erfunden und zusammengefasst. PSR schlägt eine Standardempfehlung vor (Proposing a Standards Recommendation) Abkürzung für Standards Proposal.
Detaillierte Spezifikationen und Standards finden Sie unter
PSR-Spezifikation in PHP
Die PRS-0-Spezifikation ist die erste Reihe von Spezifikationen, die sie veröffentlicht haben. Sie formuliert hauptsächlich einige automatische Ladestandards (PSR-0 hat mehrere verbindliche Anforderungen:
).1. Ein vollständig qualifizierter Namespace und eine Klasse müssen der Struktur entsprechen: „< Vendor Name>(< Namespace>)*< Class Name>“
Jeder Namespace muss Es gibt einen Namespace der obersten Ebene („Anbietername“).
3 Jeder Namespace kann mehrere Unternamespaces haben.
4 Beim Laden aus dem Dateisystem muss das Trennzeichen (/) jedes Namespace sein Konvertieren in DIRECTORY_SEPARATOR (Betriebssystem-Pfadtrennzeichen)
5. Im Klassennamen muss jedes Unterstrichsymbol (_) in DIRECTORY_SEPARATOR (Betriebssystem-Pfadtrennzeichen) konvertiert werden. Innerhalb eines Namensraums hat das Symbol underscore_ keine (besondere) Bedeutung.
6. Beim Laden aus dem Dateisystem müssen der qualifizierte Namespace und die Klasse mit .php enden
7. Verdor-Name, Namespaces und Klassennamen können aus Groß- und Kleinbuchstaben bestehen (Groß- und Kleinschreibung beachten)
Die spezifischen Regeln können etwas verwirrend sein, also fangen wir von vorne an.
Werfen wir zunächst einen Blick auf den allgemeinen Inhalt des PSR0-Standards. Die Artikel 1, 2, 3 und 7 legen Beschränkungen für die Namen von Namespaces fest, und die Artikel 4 und 5 legen die Zuordnungsbeziehung zwischen Namespaces und fest Dateiverzeichnisse Es gibt Einschränkungen, Artikel 6 ist der Dateisuffixname.
Wie bereits erwähnt, wie standardisiert der PSR-Standard die Zuordnungsbeziehung zwischen dem Namespace und dem Dateiverzeichnis, in dem er sich befindet? Dies geschieht durch Einschränkung des Namens des Namespace, des Speicherorts des Dateiverzeichnisses und der Zuordnungsbeziehung zwischen beiden.
Dann müssen wir uns vielleicht fragen: Wo ist die Beschränkung für den Speicherort des Verzeichnisses, in dem sich die Datei befindet? Tatsächlich lautet die Antwort:
Namespace-Namen einschränken + Zuordnung von Namespace-Namen und Dateiverzeichnis einschränken = Dateiverzeichnis einschränken
Okay, lass uns zuerst darüber nachdenken Welche Anpassungen müssen für ein bestimmtes Programm vorgenommen werden, wenn es den PSR0-Standard unterstützen möchte?
Zuerst muss das Programm eine Zuordnungsfunktion definieren, die den Artikeln 4 und 5 des PSR0-Standards entspricht, und diese Funktion dann in spl_register( );
Zweitens müssen beim Definieren eines neuen Namespace der Name des Namespace und der Verzeichnisspeicherort der Datei den Punkten 1, 2, 3 entsprechen. und 7.
Im Allgemeinen definieren wir zur Vereinfachung der Codewartung nur einen Namespace in einer Datei.
Okay, wir haben den Namen des Namespace, der dem PSR0-Standard entspricht, und können die Dateiverzeichnisadresse erhalten, die dem PSR0-Standard entspricht Nach dem PSR0-Standard läuft alles reibungslos. Wir können den Namespace verwenden.
Als nächstes werfen wir einen detaillierten Blick darauf, was der PSR0-Standard spezifiziert.
Nehmen wir einen der Namespaces /Symfony/Core/Request, eine der Drittanbieter-Bibliotheken Symfony in Laravel, als Beispiel, um über den oben genannten PSR0-Standard zu sprechen.
Ein vollständig qualifizierter Namespace und eine Klasse müssen der Struktur entsprechen: „< Vendor Name>(< Namespace>)* < ;Klassenname>“
/Symfony ist der Name des Anbieters, der der Name der Drittanbieter-Bibliothek ist, und /Core ist der Namespace-Name, im Allgemeinen einige Attributinformationen unseres Namespace (zum Beispiel ist Request die Kernfunktion von Symfony); schließlich ist Request der Name unseres Namespace. Diese Standardspezifikation ermöglicht es den Leuten, die Quelle und Funktion des Namespace sehr klar zu sehen , was der Entwicklung des Codes förderlich ist.
2. Jeder Namespace muss einen Top-Level-Namespace („Anbietername“) haben
Das heißt, jeder Namespace muss einen Top-Level-Namespace ähnlich wie /Symfony haben. Warum gibt es eine solche Regel? Da der PSR0-Standard nur für die Zuordnungsbeziehung nach dem Namespace der obersten Ebene verantwortlich ist, wird der Teil von /Symfony/Core/Request, dem das Verzeichnis /Symfony zugeordnet werden soll, vom Benutzer oder vom Framework selbst definiert. Der sogenannte Top-Level-Namespace ist ein Namespace mit benutzerdefinierten Zuordnungsbeziehungen, normalerweise dem Anbieternamen (dem Namen einer Drittanbieterbibliothek). Mit anderen Worten: Der Namespace der obersten Ebene ist die Grundlage für das automatische Laden. Warum sind die Standards so festgelegt? Der Grund ist sehr einfach. Wenn es einen Namespace /Symfony/Core/Transport/Request gibt und ein anderer Namespace /Symfony/Core/Transport/Request1 ist, müssen wir zwei Pfade schreiben, und zwar diese beiden Was ist, wenn es entsprechend dem Namespace Request2 und Request3 gibt? Für den Top-Level-Namespace /Symfony benötigen wir nur ein entsprechendes Verzeichnis, der Rest kann mit dem PSR-Standard geparst werden.
3. Jeder Namespace kann mehrere Unternamespaces haben
Das ist sehr einfach, Request kann definiert werden. Es kann als /Symfony/Core/Request oder als /Symfony/Core/Transport/Request definiert werden. Unter dem /Core-Namespace können viele Unternamensräume vorhanden sein du willst.
4. Beim Laden aus dem Dateisystem muss das Trennzeichen (/) jedes Namespace in DIRECTORY_SEPARATOR ( OS-Pfadtrennzeichen)
Nun kommen wir endlich zur Mapping-Spezifikation. Das /-Symbol des Namespace muss in ein Pfadtrennzeichen umgewandelt werden, was bedeutet, dass der Namespace /Symfony/Core/Request in eine Verzeichnisstruktur wie SymfonyCoreRequest umgewandelt werden muss.
5. Im Klassennamen sollte jeder Unterstrich _ in DIRECTORYSEPARATOR (Betriebssystempfadtrennzeichen) umgewandelt werden. In einem Namensraum hat das Unterstrichsymbol keine (besondere) Bedeutung.
Dieser Satz bedeutet, dass wir, wenn unser Namespace /Symfony/Core/Request_a ist, ihn einem Verzeichnis wie SymfonyCoreRequesta zuordnen sollten. Warum gibt es eine solche Bestimmung? Dies liegt daran, dass es vor PHP5 keinen Namespace gab und Programmierer ihn nur Symfony_Core_Request_a nennen konnten. Diese Bereitstellung von PSR0 soll mit dieser Situation kompatibel sein.
Die restlichen beiden sind sehr einfach und ich werde nicht auf Details eingehen.
Mit solchen Namespace-Benennungsregeln und Zuordnungsstandards können wir darüber nachdenken, wo wir die Dateien dort ablegen sollen, wo sich der Namespace befindet. Nehmen wir immer noch Symfony/Core/Request als Beispiel: Das Verzeichnis lautet /path/to/project/vendor/Symfony/Core/Request.php, wobei /path/to/project der Speicherort Ihres Projekts auf der Festplatte ist, /path /to /project/vendor ist das Verzeichnis, in dem sich alle vom Projekt verwendeten Drittanbieterbibliotheken befinden. /path/to/project/vendor/Symfony ist das Verzeichnis, das dem Top-Level-Namespace/Symfony entspricht. Die folgenden Dateiverzeichnisse sind gemäß dem PSR0-Standard eingerichtet:
/Symfony/Core/Request => /Symfony/Core/Request.php
Alles ist perfekt, oder? Nein, es gibt noch einige Mängel:
Sollten wir auch ohne Namespaces kompatibel sein?
Gemäß dem PSR0-Standard muss der Namespace /A/B/C/D/E/F einer Verzeichnisstruktur /A/B/C entsprechen /D/ E/F, ist diese Verzeichnisstruktur zu tief?
Ende 2013 der fünfte wurde veröffentlicht Spezifikation - PSR-4.
PSR-4 standardisiert die Angabe eines Dateipfads zum automatischen Laden von Klassendefinitionen und standardisiert außerdem den Speicherort automatisch geladener Dateien. Auf den ersten Blick ähnelt es dem PSR-0. Tatsächlich gibt es einige Überschneidungen in der Funktionalität. Der Unterschied besteht darin, dass die PSR-4-Spezifikation relativ sauber ist, Inhalte entfernt, die mit früheren Versionen von PHP 5.3 kompatibel sind, und sich ein wenig wie eine aktualisierte Version von PSR-0 anfühlt. Natürlich soll PSR-4 PSR-0 nicht vollständig ersetzen, sondern PSR-0 bei Bedarf ergänzen – natürlich kann PSR-4 auch PSR-0 ersetzen, wenn Sie möchten. PSR-4 kann mit anderen automatischen Lademechanismen einschließlich PSR-0 verwendet werden.
Der Unterschied zwischen PSR4-Standard und PSR0-Standard:
在类名中使用下划线没有任何特殊含义。
命名空间与文件目录的映射方法有所调整。
对第二项我们详细解释一下 ( Composer自动加载的原理):
假如我们有一个命名空间:Foo/class,Foo 是顶级命名空间,其存在着用户定义的与目录的映射关系:
<span style="font-size: 16px;">"Foo/" => "src/"<br/></span>
按照PSR0标准,映射后的文件目录是: src/Foo/class.php,但是按照 PSR4 标准,映射后的文件目录就会是:src/class.php,为什么要这么更改呢?原因就是怕命名空间太长导致目录层次太深,使得命名空间和文件目录的映射关系更加灵活。
再举一个例子,来源 PSR-4——新鲜出炉的PHP规范:
PSR-0风格
<span style="font-size: 16px;"> vendor/<br/> vendor_name/<br/> package_name/<br/> src/<br/> Vendor_Name/<br/> Package_Name/<br/> ClassName.php # Vendor_Name\Package_Name\ClassName<br/> tests/<br/> Vendor_Name/<br/> Package_Name/<br/> ClassNameTest.php # Vendor_Name\Package_Name\ClassName<br/></span>
PSR-4风格
<span style="font-size: 16px;"> vendor/<br/> vendor_name/<br/> package_name/<br/> src/<br/> ClassName.php # Vendor_Name\Package_Name\ClassName<br/> tests/<br/> ClassNameTest.php # Vendor_Name\Package_Name\ClassNameTest<br/></span>
对比以上两种结构,明显可以看出PSR-4带来更简洁的文件结构。
Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung der automatischen Ladefunktion von PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!