Heim  >  Artikel  >  Backend-Entwicklung  >  Eine Erklärung des zugrunde liegenden Funktionsmechanismus und der Prinzipien von PHP

Eine Erklärung des zugrunde liegenden Funktionsmechanismus und der Prinzipien von PHP

韦小宝
韦小宝Original
2018-02-12 09:48:111578Durchsuche

PHP gilt als einfach, aber es ist nicht leicht, es zu beherrschen. Wir müssen nicht nur in der Lage sein, es zu verwenden, sondern auch das zugrunde liegende Funktionsprinzip kennen.

PHP ist eine dynamische Sprache, die für die Webentwicklung geeignet ist. Genauer gesagt handelt es sich um ein Software-Framework, das die Sprache C verwendet, um eine große Anzahl von Komponenten zu implementieren. Im engeren Sinne kann es als leistungsstarkes UI-Framework betrachtet werden.

Was ist der Zweck, die zugrunde liegende Implementierung von PHP zu verstehen? Um dynamische Sprache gut nutzen zu können, müssen wir zunächst verstehen, dass Speicherverwaltungs- und Framework-Modelle unserer Referenz würdig sind. Durch erweiterte Entwicklung können wir leistungsfähigere Funktionen erreichen und die Leistung unserer Programme optimieren.

Das Designkonzept und die Eigenschaften von PHP

Multiprozessmodell: Da PHP ein Multiprozessmodell ist, stören sich verschiedene Anforderungen nicht gegenseitig, was gewährleistet Diese eine Anfrage wird nicht hängen bleiben. Natürlich hat PHP mit der Zeit das Multithreading-Modell unterstützt.

Schwach typisierte Sprache: Im Gegensatz zu C/C++, Java, C# und anderen Sprachen ist PHP eine schwach typisierte Sprache. Der Typ einer Variablen wird nicht zu Beginn bestimmt und es kann zu einer impliziten oder expliziten Typkonvertierung kommen. Die Flexibilität dieses Mechanismus ist in der Webentwicklung sehr praktisch sind detailliert in.

Der Motor- (Zend) + Komponentenmodus (ext) reduziert die interne Kopplung.

Die mittlere Schicht (Sapi) isoliert den Webserver und PHP.

Die Syntax ist einfach und flexibel, ohne zu viele Spezifikationen. Mängel führen zu gemischten Stilen, aber egal wie schlecht ein Programmierer ist, er wird kein Programm schreiben, das zu unverschämt ist und die Gesamtsituation gefährdet.

Das vierschichtige System von PHP

Die Kernarchitektur von PHP ist wie folgt:

Eine Erklärung des zugrunde liegenden Funktionsmechanismus und der Prinzipien von PHP

Wie Sie Aus dem Bild geht hervor, dass PHP von unten nach oben ein 4-Schichten-System ist:

Zend-Engine: Zend ist vollständig in reinem C implementiert und ist der Kernbestandteil von PHP. Es übersetzt PHP-Code (lexikalisch, Syntaxanalyse und andere Kompilierungsprozesse) verarbeiten ausführbare Opcodes und implementieren entsprechende Verarbeitungsmethoden, implementieren grundlegende Datenstrukturen (wie Hashtable, oo), Speicherzuweisung und -verwaltung und stellen entsprechende API-Methoden für externe Aufrufe bereit. Dies ist der Kern von allem und jedem Peripheriegeräte sind alle rund um Zend implementiert.

Erweiterungen: Rund um die Zend-Engine stellen Erweiterungen verschiedene grundlegende Dienste auf Komponentenbasis bereit. Unsere gemeinsamen verschiedenen integrierten Funktionen (z. B. Array-Serien), Standardbibliotheken usw. werden alle durch Erweiterungen implementiert. und Benutzer können auch Ihre eigene Erweiterung nach Bedarf implementieren, um Funktionserweiterungen, Leistungsoptimierungen und andere Zwecke zu erreichen (z. B. sind die PHP-Mittelschicht und die Rich-Text-Analyse, die derzeit von Tieba verwendet werden, typische Erweiterungsanwendungen).

Sapi: Der vollständige Name von Sapi ist Server Application Programming Interface. Dabei handelt es sich um die Server-Anwendungsprogrammierschnittstelle, die es PHP ermöglicht, über eine Reihe von Hook-Funktionen mit Peripheriedaten zu interagieren Durch Sapi wird PHP selbst erfolgreich von Anwendungen der oberen Ebene entkoppelt und isoliert. PHP kann nicht mehr berücksichtigen, wie es mit verschiedenen Anwendungen kompatibel ist, und die Anwendung selbst kann auch unterschiedliche Verarbeitungsmethoden entsprechend ihren eigenen Eigenschaften implementieren.

Anwendung der oberen Ebene: Dies ist das PHP-Programm, das wir normalerweise schreiben. Wir erhalten verschiedene Anwendungsmodi über verschiedene Sapi-Methoden, z. B. die Implementierung von Webanwendungen über einen Webserver, deren Ausführung im Skriptmodus auf der Befehlszeile usw.

Wenn PHP ein Auto ist, dann ist der Rahmen des Autos PHP selbst, Zend ist der Motor des Autos (Motor), die verschiedenen Komponenten unter Ext sind die Räder des Autos und Sapi kann betrachtet werden als Straße

Autos können auf verschiedenen Arten von Straßen fahren, und die Ausführung eines PHP-Programms bedeutet, dass das Auto auf der Straße fährt. Deshalb brauchen wir: einen leistungsstarken Motor + die richtigen Räder + die richtige Spur.

3.Sapi

Wie oben erwähnt, ermöglicht Sapi externen Anwendungen den Datenaustausch mit PHP über eine Reihe von Schnittstellen und kann spezifische Funktionen entsprechend den Eigenschaften verschiedener Schnittstellen implementieren Einige unserer gängigen Sapi-Verarbeitungsmethoden sind:

Apache2handler: Dies ist die Verarbeitungsmethode, wenn Apache als Webserver verwendet wird und im mod_PHP-Modus ausgeführt wird.

cgi: Dies ist eine weitere direkte Interaktionsmethode zwischen Webserver und PHP, das berühmte Fastcgi-Protokoll. In den letzten Jahren wurde fastcgi + PHP immer häufiger verwendet und ist auch die einzige Methode, die von Asynchron unterstützt wird Webserver.

cli: Anwendungsmodus für Befehlszeilenaufrufe

4. PHP-Ausführungsprozess und Opcode

Werfen wir zunächst einen Blick auf den Ausführungsprozess von PHP Code-Prozess.


Eine Erklärung des zugrunde liegenden Funktionsmechanismus und der Prinzipien von PHP


Wie Sie auf dem Bild sehen können, implementiert PHP einen typischen dynamischen Sprachausführungsprozess: nach Erhalt eines Codestücks Nach der lexikalischen Analyse, der Syntaxanalyse und anderen Schritten wird das Quellprogramm nacheinander in Anweisungen

(Opcodes) übersetzt, und dann führt die virtuelle ZEND-Maschine diese Anweisungen nacheinander aus, um den Vorgang abzuschließen. PHP selbst ist in C implementiert, daher sind die letztendlich aufgerufenen Funktionen alle C-Funktionen. Tatsächlich können wir uns PHP als eine in C entwickelte Software vorstellen.

Der Kern der PHP-Ausführung sind die übersetzten Anweisungen, also der Opcode.

Opcode ist die grundlegendste Einheit der PHP-Programmausführung. Ein Opcode besteht aus zwei Parametern (op1, op2), einem Rückgabewert und einer Verarbeitungsfunktion. Das PHP-Programm wird letztendlich in die sequentielle Ausführung einer Reihe von Opcode-Verarbeitungsfunktionen übersetzt.

Mehrere gängige Verarbeitungsfunktionen:

 ZEND_ASSIGN_SPEC_CV_CV_HANDLER : 变量分配 ($a=$b)
 ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER:函数调用
 ZEND_CONCAT_SPEC_CV_CV_HANDLER:字符串拼接 $a.$b
 ZEND_ADD_SPEC_CV_CONST_HANDLER: 加法运算 $a+2
 ZEND_IS_EQUAL_SPEC_CV_CONST:判断相等 $a==1
 ZEND_IS_IDENTICAL_SPEC_CV_CONST:判断相等 $a===1

5.HashTable – Kerndatenstruktur

HashTable ist die Kerndatenstruktur von Zend Wird zur Implementierung fast aller gängigen Funktionen verwendet. Darüber hinaus werden in Zend auch Funktionssymboltabellen, globale Variablen usw. implementiert.

Die Hash-Tabelle von PHP verfügt über die folgenden Funktionen:

Unterstützt typische Schlüssel->Wert-Abfragen

Kann als Array verwendet werden

Knoten hinzufügen und löschen sind O(1)-Komplexität

Schlüssel unterstützt gemischte Typen: assoziatives Zahlenkombinationsindex-Array existiert gleichzeitig

Wert unterstützt gemischte Typen: Array ("string", 2332)

unterstützte lineare Durchquerung: Zum Beispiel foreach

Zend-Hash-Tabelle implementiert eine typische Hash-Tabellen-Hash-Struktur und bietet gleichzeitig die Funktion der Vorwärts- und Rückwärtsdurchquerung des Arrays durch Anhängen einer doppelt verknüpften Liste. Seine Struktur ist wie folgt:

Eine Erklärung des zugrunde liegenden Funktionsmechanismus und der Prinzipien von PHP

Wie Sie sehen können, gibt es in der Hash-Tabelle sowohl Hash-Strukturen in Form eines Schlüssel->Werts als auch eines doppelt verknüpften Listenmodus. Dadurch ist es sehr praktisch, unterstützt schnelle Suche und lineares Durchqueren.

Hash-Struktur: Die Hash-Struktur von Zend ist ein typisches Hash-Tabellenmodell, das eine verknüpfte Liste verwendet, um Konflikte zu lösen. Es ist zu beachten, dass die Hash-Tabelle von Zend eine selbstwachsende Datenstruktur ist. Wenn die Anzahl der Hash-Tabellen voll ist, wird sie dynamisch um das Zweifache erweitert und Elemente neu positioniert. Die Anfangsgröße beträgt 8. Darüber hinaus hat Zend selbst bei der Durchführung der schnellen Schlüssel->Wertsuche einige Optimierungen vorgenommen, um den Prozess durch den Austausch von Raum gegen Zeit zu beschleunigen. Beispielsweise wird in jedem Element eine Variable nKeyLength verwendet, um die Länge des Schlüssels zur schnellen Bestimmung zu identifizieren.

Doppelt verknüpfte Liste: Die Zend-Hash-Tabelle implementiert die lineare Durchquerung von Elementen durch eine verknüpfte Listenstruktur. Theoretisch reicht es aus, eine einseitig verknüpfte Liste zum Durchlaufen zu verwenden. Der Hauptzweck der Verwendung einer zweiseitig verknüpften Liste besteht darin, das Durchlaufen schnell zu löschen und zu vermeiden. Die Zend-Hash-Tabelle ist eine zusammengesetzte Struktur, die gängige assoziative Arrays unterstützt und auch als sequentielle Indexnummern verwendet werden kann und sogar eine Mischung aus beiden ermöglicht.

PHP-Assoziatives Array: Assoziatives Array ist eine typische hash_table-Anwendung. Ein Abfrageprozess durchläuft die folgenden Schritte (wie aus dem Code ersichtlich ist, handelt es sich hierbei um einen üblichen Hash-Abfrageprozess und es werden einige schnelle Beurteilungen hinzugefügt, um die Suche zu beschleunigen.):

 getKeyHashValue h;
 index = n & nTableMask;
 Bucket *p = arBucket[index];
 while (p) {
 if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
 RETURN p->data;
 }
 p=p->next;
 }
 RETURN FALTURE;

PHP-Index-Array : Das Index-Array ist das, was wir üblicherweise als Array of sehen, auf das über einen Index zugegriffen wird. Beispiel: $arr[0], Zend HashTable wird intern normalisiert und der Hash-Wert und nKeyLength (0) werden auch dem Indextypschlüssel zugewiesen. Die interne Mitgliedsvariable nNextFreeElement ist die aktuell zugewiesene maximale ID, die nach jedem Push automatisch um eins erhöht wird. Es ist dieser Normalisierungsprozess, der es PHP ermöglicht, eine Mischung aus assoziativen und nicht-assoziativen Daten zu erreichen. Aufgrund der Besonderheit des Push-Vorgangs wird die Reihenfolge der Indexschlüssel im PHP-Array nicht durch die Größe des Index bestimmt, sondern durch die Reihenfolge des Pushs. Zum Beispiel: $arr[1] = 2; $arr[2] = 3; für Schlüssel vom Typ Double behandelt Zend HashTable sie als Indexschlüssel

6 >PHP ist eine schwach typisierte Sprache und unterscheidet die Variablentypen nicht streng. PHP muss beim Deklarieren von Variablen den Typ nicht angeben. PHP kann während der Programmausführung implizite Konvertierungen von Variablentypen durchführen. Wie bei anderen stark typisierten Sprachen kann auch eine explizite Typkonvertierung im Programm durchgeführt werden. PHP-Variablen können in einfache Typen (int, string, bool), Sammlungstypen (Array-Ressourcenobjekt) und Konstanten (const) unterteilt werden. Alle oben genannten Variablen haben unter der Haube die gleiche zval-Struktur.

Zval ist eine weitere sehr wichtige Datenstruktur in Zend, die zum Identifizieren und Implementieren von PHP-Variablen verwendet wird. Die Datenstruktur ist wie folgt:

Eine Erklärung des zugrunde liegenden Funktionsmechanismus und der Prinzipien von PHPZval besteht hauptsächlich aus aus drei Teilen zusammengesetzt:

    Typ: Gibt den Typ der Variablen an (Ganzzahl, Zeichenfolge, Array usw.)
  • refcount&is_ref: verwendet Referenzzählung implementieren (detaillierte Einführung später)
  • Wert: Der Kernteil, der die tatsächlichen Daten der Variablen speichert
  • Zvalue wird verwendet Speichern Sie eine variable Ist-Daten. Da mehrere Typen gespeichert werden müssen, ist zvalue eine Union und implementiert somit eine schwache Typisierung.

Die entsprechende Beziehung zwischen PHP-Variablentypen und ihrem tatsächlichen Speicher ist wie folgt:

Referenzzählung wird häufig beim Speicherrecycling, bei String-Operationen usw. verwendet. Variablen in PHP sind eine typische Anwendung der Referenzzählung. Die Referenzzählung von Zval wird über die Mitgliedsvariablen is_ref und ref_count implementiert. Durch die Referenzzählung können mehrere Variablen dieselben Daten teilen. Vermeiden Sie den enormen Verbrauch, der durch häufiges Kopieren entsteht.
 IS_LONG -> lvalue
 IS_DOUBLE -> dvalue
 IS_ARRAY -> ht
 IS_STRING -> str
 IS_RESOURCE -> lvalue

Beim Ausführen einer Zuweisungsoperation verweist Zend die Variable auf denselben zval und ref_count++ und während der nicht gesetzten Operation auf den entsprechenden ref_count-1. Der Zerstörungsvorgang wird nur ausgeführt, wenn ref_count auf 0 reduziert wird. Wenn es sich um eine Referenzzuweisung handelt, ändert Zend is_ref auf 1.

PHP-Variablen realisieren die gemeinsame Nutzung von Daten durch Referenzzählung. Was passiert, wenn Sie den Wert einer der Variablen ändern? Wenn Zend beim Versuch, eine Variable zu schreiben, feststellt, dass der ZVAL, auf den die Variable zeigt, von mehreren Variablen gemeinsam genutzt wird, kopiert es einen ZVAL mit einem Ref_Count von 1 und verringert den Refcount des ursprünglichen ZVAL. Dieser Vorgang wird als „ZVAL-Trennung“ bezeichnet ". Es ist ersichtlich, dass Zend den Kopiervorgang nur dann ausführt, wenn ein Schreibvorgang auftritt. Daher wird er auch als Copy-on-Write (Kopieren beim Schreiben) bezeichnet.

Für Referenzvariablen gilt: Die Anforderungen sind die gleichen wie bei Nichtreferenzen. Im Gegensatz dazu müssen durch Referenz zugewiesene Variablen gebündelt werden. Durch Ändern einer Variablen werden alle gebündelten Variablen geändert.

Ganzzahlen und Gleitkommazahlen gehören zu den Grundtypen in PHP und sind auch einfache Variablen. Für Ganzzahlen und Gleitkommazahlen werden die entsprechenden Werte direkt in zvalue gespeichert. Ihre Typen sind lang bzw. doppelt.

Wie aus der zvalue-Struktur ersichtlich ist, unterscheidet PHP bei ganzzahligen Typen im Gegensatz zu stark typisierten Sprachen wie c nicht zwischen int, unsignedint, long, long

long und anderen Es gibt beispielsweise nur einen Ganzzahltyp, der lang ist. Daraus ist ersichtlich, dass in PHP der Wertebereich von Ganzzahlen durch die Anzahl der Compiler-Bits bestimmt wird und nicht festgelegt ist.

Bei Gleitkommazahlen wird, ähnlich wie bei ganzen Zahlen, nicht zwischen Float und Double, sondern nur Double unterschieden.

Was soll ich in PHP tun, wenn der Ganzzahlbereich außerhalb der Grenzen liegt? In diesem Fall wird es automatisch in den Double-Typ konvertiert. Sie müssen dabei vorsichtig sein, da dies zu vielen Tricks führt.

Zeichenvariablen sind wie Ganzzahlen auch Grundtypen und einfache Variablen in PHP. Aus der zvalue-Struktur ist ersichtlich, dass in PHP ein String aus einem Zeiger auf die tatsächlichen Daten und einer Längenstruktur

besteht, die dem String in C++ ähnelt. Da die Länge im Gegensatz zu c durch eine tatsächliche Variable dargestellt wird, kann ihre Zeichenfolge aus binären Daten bestehen (einschließlich

Ressourcenzerstörung: Die Datentypen von Ressourcen sind vielfältig. Zend selbst hat keine Möglichkeit, es zu zerstören. Daher müssen Benutzer bei der Registrierung von Ressourcen eine Zerstörungsfunktion bereitstellen. Wenn Ressourcen nicht festgelegt sind, ruft Zend die entsprechende Funktion auf, um die Zerstörung abzuschließen. Löschen Sie es auch aus der globalen Ressourcentabelle.

Ressourcen können lange Zeit bestehen bleiben, nicht nur nachdem alle Variablen, die auf sie verweisen, den Gültigkeitsbereich verlassen, sondern auch nachdem eine Anfrage beendet und eine neue Anfrage generiert wurde. Diese Ressourcen werden als persistente Ressourcen bezeichnet, da sie während des gesamten Lebenszyklus der SAPI bestehen bleiben, sofern sie nicht ausdrücklich zerstört werden. In vielen Fällen können persistente Ressourcen die Leistung bis zu einem gewissen Grad verbessern. In unserem gemeinsamen mysql_pconnect weisen persistente Ressourcen beispielsweise Speicher über pemalloc zu, sodass sie nicht freigegeben werden, wenn die Anforderung endet. Für Zend gibt es per se keinen Unterschied zwischen den beiden.

Wie werden lokale Variablen und globale Variablen in PHP implementiert? Bei einer Anfrage kann PHP jederzeit zwei Symboltabellen (symbol_table und

active_symbol_table) sehen, wobei erstere zur Verwaltung globaler Variablen verwendet wird. Letzteres ist ein Zeiger, der auf die aktuell aktive Variablensymboltabelle zeigt. Wenn das Programm eine Funktion aufruft, weist zend

ihr eine Symboltabelle x zu und zeigt active_symbol_table auf a. Auf diese Weise wird die Unterscheidung zwischen globalen und lokalen Variablen erreicht.

Variablenwerte abrufen: Die PHP-Symboltabelle wird über hash_table implementiert. Beim Abrufen wird der entsprechende zval entsprechend der Kennung ermittelt und zurückgegeben.

Globale Variablen in Funktionen verwenden: In Funktionen können wir globale Variablen verwenden, indem wir sie explizit als global deklarieren. Erstellen Sie einen Verweis auf die Variable mit demselben Namen in symbol_table in active_symbol_table. Wenn in symbol_table keine Variable mit demselben Namen vorhanden ist, wird diese zuerst erstellt.

Verwandte Artikel:

Eingehende Interpretation des PHP-Betriebsmechanismus

Eingehende Interpretation von PHP Betätigungsmechanismus. Werfen wir einen Blick auf den folgenden PHP-Betriebsmechanismusprozess: 1. Wir haben die PHP-bezogenen Prozesse nie manuell gestartet, sondern mit dem Ap...

Das obige ist der detaillierte Inhalt vonEine Erklärung des zugrunde liegenden Funktionsmechanismus und der Prinzipien von PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn