Heim >Backend-Entwicklung >PHP-Problem >Detaillierte Einführung in das zugrunde liegende Funktionsprinzip von PHP

Detaillierte Einführung in das zugrunde liegende Funktionsprinzip von PHP

王林
王林Original
2019-09-02 13:13:174601Durchsuche

Detaillierte Einführung in das zugrunde liegende Funktionsprinzip von PHP

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 Komponentenmodulen zu implementieren. Es ist ein leistungsstarkes UI-Framework.

Kurz gesagt; dynamischer PHP-Sprachausführungsprozess: Nach Erhalt eines Codestücks, nach lexikalischer Analyse, Syntaxanalyse und anderen Schritten wird das Quellprogramm in Anweisungen (Opcodes) und dann in die virtuelle ZEND-Maschine übersetzt Führen Sie diese Anweisungen einmal aus, um den Vorgang abzuschließen. PHP selbst ist in C implementiert, daher sind die letztendlich aufgerufenen Funktionen auch C-Funktionen. Tatsächlich können wir PHP als eine in C entwickelte Software betrachten.

1. Das Designkonzept und die Eigenschaften von PHP

1. Da PHP ein Multiprozessmodell ist, gilt dies nicht für verschiedene Anforderungen Sie stören sich gegenseitig, sodass sichergestellt ist, dass der Ausfall einer Anfrage nicht den gesamten Dienst beeinträchtigt. Derzeit unterstützt PHP bereits das Multithreading-Modell.

2. 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.

3. Das Modell Engine (Zend) + Komponente (ext) reduziert die interne Kopplung.

4. Die mittlere Schicht (Sapi) Der vollständige Name von Sapi ist Server Application Programming Interface, das den Webserver und PHP isoliert.

5. Die Syntax ist einfach und flexibel, ohne zu viele Spezifikationen. Nachteile führen zu einer Stilmischung.

2. Das vierschichtige System von PHP

Die Kernarchitektur von PHP ist wie folgt:

Detaillierte Einführung in das zugrunde liegende Funktionsprinzip von PHP

PHP ist ein 4-Schichten-System Ebenensystem von unten nach oben System:

1. Zend-Engine: Zend ist vollständig in reinem C implementiert und ist der Kernbestandteil von PHP. Es übersetzt PHP-Code (eine Reihe von Kompilierungsvorgängen wie lexikalische und Syntaxanalyse). ) in ausführbare Opcode-Verarbeitung und -Implementierung. Entsprechende Verarbeitungsmethoden, die Implementierung grundlegender Datenstrukturen (wie Hashtable, OO), Speicherzuweisungsmechanismen und -verwaltung sowie die Bereitstellung entsprechender API-Methoden für externe Aufrufe sind der Kern von allem. Alle Peripheriefunktionen werden rund um Zend implementiert .

2. Erweiterungen: Rund um die Zend-Engine stellen Erweiterungen verschiedene Basisdienste auf Komponentenbasis bereit. Unsere gemeinsamen verschiedenen integrierten Funktionen (Array-Serien), Standardbibliotheken usw. werden alle durch Erweiterungen implementiert. Benutzer können bei Bedarf auch typische Anwendungen Ihrer eigenen Erweiterung implementieren.

3. 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 zu interagieren Erfolgreiches Design von PHP. PHP selbst ist erfolgreich von der übergeordneten Anwendung 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 .

4. Dies ist das PHP-Programm, das wir normalerweise schreiben. Wir erhalten verschiedene Anwendungsmodi über verschiedene Spai-Methoden und führen sie im Skriptmodus auf der Befehlszeile aus. usw. warten.

Wir brauchen: einen Hochleistungsmotor (Zend) + die richtigen Räder (Ext) + die richtige Spur (Sapi).

3. Sapi

Sapi ermöglicht externen Anwendungen den Datenaustausch mit PHP über eine Reihe von Schnittstellen und die Implementierung spezifischer Verarbeitungsmethoden entsprechend unterschiedlicher Anwendungsmerkmale:

1. Apache2handler: Dies ist die Verarbeitungsmethode, wenn Apache als Webserver verwendet und im mod_PHP-Modus ausgeführt wird. Sie ist derzeit auch die am weitesten verbreitete.

2. CGI: Dies ist eine weitere direkte Interaktionsmethode zwischen Webserver und PHP. In letzter Zeit wird fastcgi + PHP immer häufiger verwendet und ist auch die einzige, die von Asynchron unterstützt wird Webserver. Methode; typischer Nginx-Server; ist einfach eine Erweiterung von PHP.

Laden Sie den FastCGI-Prozessmanager (IIS ISAPI oder Apache-Modul), wenn der Webserver startet

Der FastCGI-Prozessmanager initialisiert sich selbst und startet mehrere CGI-Interpreterprozesse (sichtbar mehrere PHP-CGI) und wartet für die Verbindung vom Webserver.

Wenn eine Client-Anfrage den Webserver erreicht, wählt der FastCGI-Prozessmanager einen CGI-Interpreter aus und stellt eine Verbindung zu ihm her. Der Webserver sendet CGI-Umgebungsvariablen und Standardeingaben an den FastCGI-Unterprozess php-cgi.

Nachdem der FastCGI-Unterprozess die Verarbeitung abgeschlossen hat, gibt er über dieselbe Verbindung Standardausgabe- und Fehlerinformationen an den Webserver zurück. Wenn der untergeordnete FastCGI-Prozess die Verbindung schließt, wird die Anfrage verarbeitet. Der untergeordnete FastCGI-Prozess wartet dann auf die nächste Verbindung vom FastCGI-Prozessmanager (der auf dem Webserver ausgeführt wird) und verarbeitet diese. Im CGI-Modus wird php-cgi an dieser Stelle beendet.

Im obigen Fall können Sie sich vorstellen, wie langsam CGI normalerweise ist. Jede Webanfrage an PHP muss php.ini erneut analysieren, alle Erweiterungen neu laden und alle Datenstrukturen neu initialisieren. Bei FastCGI geschieht dies alles nur einmal, nämlich beim Start des Prozesses. Ein zusätzlicher Bonus besteht darin, dass dauerhafte Datenbankverbindungen funktionieren.

Detaillierte Einführung in das zugrunde liegende Funktionsprinzip von PHP

Detaillierte Einführung in das zugrunde liegende Funktionsprinzip von PHP

3. cli: Anwendungsmodus, der über die Befehlszeile aufgerufen wird

Befehlszeilenschnittstelle (englisch: command-line interface, Abkürzung). : CLI) ist die am weitesten verbreitete Benutzeroberfläche vor der Popularität grafischer Benutzeroberflächen. Sie unterstützt normalerweise nicht die Maus. Der Benutzer gibt Anweisungen über die Tastatur ein und der Computer führt die Anweisungen aus. Manche Leute nennen es auch Character User Interface (CUI).
Es wird allgemein angenommen, dass die Befehlszeilenschnittstelle (CLI) nicht so benutzerfreundlich ist wie die grafische Benutzeroberfläche (GUI). Da Befehlszeilenschnittstellensoftware normalerweise erfordert, dass sich der Benutzer die Betriebsbefehle merkt, spart die Befehlszeilenschnittstelle aufgrund ihrer eigenen Eigenschaften im Vergleich zur grafischen Benutzeroberfläche Computersystemressourcen. Unter der Prämisse, sich die Befehle zu merken, ist die Verwendung der Befehlszeilenschnittstelle oft schneller als die Verwendung der grafischen Benutzeroberfläche. Daher behalten Betriebssysteme mit grafischer Benutzeroberfläche optionale Befehlszeilenschnittstellen bei.

4. PHP-Ausführungsprozess

Detaillierte Einführung in das zugrunde liegende Funktionsprinzip von PHP

PHP-dynamischer Sprachausführungsprozess: Nach dem Erhalten eines Codestücks, nach der lexikalischen Analyse, der Grammatik Nach der Analyse und anderen Phasen wird das Quellprogramm 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 auch C-Funktionen. Tatsächlich können wir PHP als eine in C entwickelte Software betrachten.

Der Kern der PHP-Ausführung sind die übersetzten Anweisungen, die auch Opcodes sind.

Opcode ist die grundlegendste Einheit der PHP-Programmausführung.

In der Informatik wird Operationscode (OPCode) verwendet, um Anweisungen in Maschinensprache zu beschreiben und den Teil des Maschinencodes anzugeben, der eine bestimmte Operation ausführen soll. Das Befehlsformat und die Spezifikationen, aus denen OPCode besteht, werden verarbeitet durch die Anweisungsspezifikation des Geräts angegeben.

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 In PHP wird zur Implementierung fast aller gängigen Funktionen verwendet. Darüber hinaus basieren innerhalb von Zend auch Funktionssymboltabellen, globale Variablen usw. auf Hash-Tabellen und weisen die folgenden Merkmale auf :

1. Unterstützt typische Schlüssel-Wert-Abfragen

Kann als Array verwendet werden

3. Das Hinzufügen und Löschen von Knoten ist O(1). 🎜>

4. Schlüssel unterstützt gemischte Typen: Zugehöriges Zahlenkombinationsindex-Array

existiert gleichzeitig. 5. Wert unterstützt gemischte Typen: array("string",2332)

6. Unterstützt lineare Durchquerung: wie foreach

Die Zend-Hash-Tabelle implementiert die 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:

Detaillierte Einführung in das zugrunde liegende Funktionsprinzip von PHP

Wie Sie sehen können: Es gibt sowohl Schlüssel->Wert-Hash-Strukturen als auch doppelt verknüpfte Listenmodi in der Hash-Tabelle, was sie sehr praktisch macht Unterstützt schnelle Suche und lineare Durchquerung.

1. Hash-Struktur: Die Hash-Struktur von Zend ist ein typisches Hash-Tabellenmodell, das Konflikte durch eine verknüpfte Liste löst. 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.

2. 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 Urteile 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;

4、PHP索引数组:索引数组就是我们常见的数组,通过下标访问。例如 $arr[0],Zend HashTable内部进行了归一化处理,对于index类型key同样分配了hash值和nKeyLength(为0)。内部成员变量 nNextFreeElement就是当前分配到的最大id,每次push后自动加一。正是这种归一化处理,PHP才能够实现关联和非关联的混合。由于 push操作的特殊性,索引key在PHP数组中先后顺序并不是通过下标大小来决定,而是由push的先后决定。例如 $arr[1] = 2; $arr[2] = 3;对于double类型的key,Zend HashTable会将他当做索引key处理。

六、Hash Table变量

PHP是一门弱类型语言,本身不严格区分变量的类型。PHP在变量申明的时候不需要指定类型。

PHP在程序运行期间可能进行变量类型的隐示转换。 和其他强类型语言一样,程序中也可以进行显示的类型转换。

PHP变量可以分为简单类型(int、string、bool)、集合类型(array resource object)和常量(const)。以上所有的变量在底层都是同一种结构 zval。

Zval主要由三部分组成:

type:指定了变量所述的类型(整数、字符串、数组等)

refcount&is_ref:用来实现引用计数(后面具体介绍)

value:核心部分,存储了变量的实际数据

Zvalue是用来保存一个变量的实际数据。因为要存储多种类型,所以zvalue是一个union,也由此实现了弱类型。

引用计数在内存回收、字符串操作等地方使用非常广泛。PHP中的变量就是引用计数的典型应用。Zval的引用计数通过成员变量is_ref和ref_count实现,通过引用计数,多个变量可以共享同一份数据。避免频繁拷贝带来的大量消耗。在进行赋值操作时,zend将变量指向相同的zval同时ref_count++,在unset操作时,对应的ref_count-1。只有ref_count减为0时才会真正执行销毁操作。如果是引用赋值,则zend会修改is_ref为1。

PHP变量通过引用计数实现变量共享数据,那如果改变其中一个变量值呢?当试图写入一个变量时,Zend若发现该变量指向的zval被多个变量共 享,则为其复制一份ref_count为1的zval,并递减原zval的refcount,这个过程称为“zval分离”。可见,只有在有写操作发生时 zend才进行拷贝操作,因此也叫copy-on-write(写时拷贝)对于引用型变量,其要求和非引用型相反,引用赋值的变量间必须是捆绑的,修改一个变量就修改了所有捆绑变量。整数、浮点数是PHP中的基础类型之一,也是一个简单型变量。对于整数和浮点数,在zvalue中直接存储对应的值。其类型分别是long和double。

从zvalue结构中可以看出,对于整数类型,和c等强类型语言不同,PHP是不区分int、unsigned int、long、long long等类型的,对它来说,整数只有一种类型也就是long。由此,可以看出,在PHP里面,整数的取值范围是由编译器位数来决定而不是固定不变的。

对于浮点数,类似整数,它也不区分float和double而是统一只有double一种类型。在PHP中,如果整数范围越界了怎么办?这种情况下会自动转换为double类型,这个一定要小心,很多trick都是由此产生。

和整数一样,字符变量也是PHP中的基础类型和简单型变量。通过zvalue结构可以看出,在PHP中,字符串是由由指向实际数据的指针和长度结 构体组成,这点和c++中的string比较类似。由于通过一个实际变量表示长度,和c不同,它的字符串可以是2进制数据(包含\0),同时在PHP中, 求字符串长度strlen是O(1)操作。在新增、修改、追加字符串操作时,PHP都会重新分配内存生成新的字符串。最后,出于安全考虑,PHP在生成一个字符串时末尾仍然会添加\0。

常见的字符串拼接方式及速度比较:假设有如下4个变量:$strA=‘123’; $strB = ‘456’; $intA=123; intB=456;

现在对如下的几种字符串拼接方式做一个比较和说明:

$res = $strA.$strB和$res = “$strA$strB”
这种情况下,zend会重新malloc一块内存并进行相应处理,其速度一般
$strA = $strA.$strB
这种是速度最快的,zend会在当前strA基础上直接relloc,避免重复拷贝
$res = $intA.$intB
这种速度较慢,因为需要做隐式的格式转换,实际编写程序中也应该注意尽量避免
$strA = sprintf (“%s%s”,$strA.$strB);
这会是最慢的一种方式,因为sprintf在PHP中并不是一个语言结构,本身对于格式识别和处理就需要耗费比较多时间,另外本身机制

也是malloc内存。不过sprintf的方式最具可读性,实际中可以根据具体情况灵活选择。

PHP的数组通过Zend HashTable来天然实现。foreach操作如何实现?对一个数组的foreach就是通过遍历hashtable中的双向链表完成。对于索引数组,通过foreach遍 历效率比for高很多,省去了key->value的查找。count操作直接调用 HashTable->NumOfElements,O(1)操作。对于’123’这样的字符串,zend会转换为其整数形 式。$arr[‘123’]和$arr[123]是等价的

Ressourcentypvariable ist die komplexeste Variable in PHP und auch eine zusammengesetzte Struktur. Zval von PHP kann eine Vielzahl von Datentypen darstellen, es ist jedoch schwierig, benutzerdefinierte Datentypen vollständig zu beschreiben. Da es keine effiziente Möglichkeit gibt, diese zusammengesetzten Strukturen darzustellen, gibt es keine Möglichkeit, herkömmliche Operatoren für sie zu verwenden. Um dieses Problem zu lösen, müssen Sie lediglich über einen im Wesentlichen willkürlichen Bezeichner (Label), der als Ressource bezeichnet wird, auf den Zeiger verweisen.

In zval wird lval für Ressourcen als Zeiger verwendet, der direkt auf die Adresse der Ressource zeigt. Die Ressource kann eine beliebige zusammengesetzte Struktur sein. Die bekannten Ressourcen mysqli, fsock, memcached usw.

So verwenden Sie Ressourcen:

Registrierung: Sie möchten einen benutzerdefinierten Datentyp als Ressource verwenden. Zuerst müssen Sie es registrieren, und Zend weist ihm eine weltweit eindeutige Kennung zu.

Eine Ressourcenvariable abrufen: Für Ressourcen verwaltet Zend eine id->hash_tale der tatsächlichen Daten. Für eine Ressource wird nur ihre ID in zval aufgezeichnet. Suchen Sie beim Abrufen den spezifischen Wert in der hash_table über die ID und geben Sie ihn zurück.

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 aus der Tabelle gefunden und entsprechend der Kennung 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.

Empfohlenes PHP-Video-Tutorial für die chinesische Website: PHP-Video-Tutorial

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in das zugrunde liegende Funktionsprinzip 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

In Verbindung stehende Artikel

Mehr sehen