PHP ist eine analytische Hochsprache. Aus der Sicht des Zend-Kernels ist PHP eine Hauptfunktion Der Kernel verarbeitet das Ausgabeergebnis. Der Prozess, bei dem der Kernel den PHP-Code in ein erkennbares C-Programm „übersetzt“, ist die Kompilierung von PHP.
Empfohlener Kurs: PHP-Tutorial
Das C-Programm kompiliert während der Kompilierung eine Codezeile in Maschinencode, und jede Operation wird als betrachtet Bei einer Maschinenanweisung werden diese Anweisungen in das kompilierte Binärprogramm geschrieben. Während der Ausführung wird das Binärprogramm in den entsprechenden Speicherbereich (Konstantenbereich, Datenbereich, Codebereich) geladen, der laufende Stapel zugewiesen und dann vom Code aus gestartet Bereich starten. Dies ist ein einfacher Prozess zum Kompilieren und Ausführen eines C-Programms.
In ähnlicher Weise ähnelt die Kompilierung von PHP der von gewöhnlichen C-Programmen, mit der Ausnahme, dass der PHP-Code nicht in Maschinencode kompiliert, sondern in mehrere Opcode-Arrays analysiert wird. Jeder Opcode ist eine gewöhnliche Struktur in C. und seine Bedeutung entspricht C. Der Ausführungsprozess der Maschinenanweisungen des Programms besteht darin, dass die Engine Opcodes nacheinander ausführt. Wenn wir beispielsweise eine Variable in PHP definieren: $a = 123;
, besteht die endgültige Ausführung im Kernel darin, a zu mallocieren Speicherbereich und schreiben Sie dann den Wert hinein.
In der Datei zend_compile.h ist die Opcode-Struktur:
struct _zend_op { const void *handler; //对应执行的C语言function,即每条opcode都有一个C function处理 znode_op op1; //操作数1 znode_op op2; //操作数2 znode_op result; //返回值 uint32_t extended_value; uint32_t lineno; zend_uchar opcode; //opcode指令 zend_uchar op1_type; //操作数1类型 zend_uchar op2_type; //操作数2类型 zend_uchar result_type; //返回值类型 };
Die Aufgabe des PHP-Parsing-Prozesses besteht also darin, den PHP-Code (durch lexikalische Analyse re2c, Syntaxanalyse bison) in einen Opcode umzuwandeln Array, im Code Alle Informationen werden im Opcode gespeichert, und dann wird das Opcode-Array zur Ausführung an die Zend-Engine übergeben. Der Opcode ist der spezifische Befehl, der vom Kernel ausgeführt wird, z. B. Zuweisungs-, Additions- und Subtraktionsoperationen Aufrufe usw. Jeder Opcode entspricht einem Verarbeitungshandle. Diese Handler sind im Voraus definierte C-Funktionen.
struct _zend_op_array { //common是普通函数或类成员方法对应的opcodes快速访问时使用的字段 /* Common elements */ zend_uchar type; zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */ uint32_t fn_flags; zend_string *function_name; zend_class_entry *scope; zend_function *prototype; uint32_t num_args; uint32_t required_num_args; zend_arg_info *arg_info; /* END of common elements */ uint32_t *refcount; uint32_t last; //opcode指令数组 zend_op *opcodes; //PHP代码里定义的变量数:op_type为IS_CV的变量,不含IS_TMP_VAR、IS_VAR的 //编译前此值为0,然后发现一个新变量这个值就加1 int last_var; //临时变量数:op_type为IS_TMP_VAR、IS_VAR的变量 uint32_t T; //PHP变量名数组 zend_string **vars;//这个数组在ast编译期间配合last_var用来确定各个变量的编号,非常重要的一步操作 int last_live_range; int last_try_catch; zend_live_range *live_range; zend_try_catch_element *try_catch_array; //静态变量符号表:通过static声明的 /* static variables support */ HashTable *static_variables; zend_string *filename; uint32_t line_start; uint32_t line_end; zend_string *doc_comment; uint32_t early_binding; /* the linked list of delayed declarations */ //字面量数量 int last_literal; //字面量(常量)数组,这些都是在PHP代码定义的一些值 zval *literals; //运行时缓存数组大小 int cache_size; //运行时缓存,主要用于缓存一些znode_op以便于快速获取数据,后面单独介绍这个机制 void **run_time_cache; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; };
Opcode-Anweisung: die spezifische Verarbeitungsaktion, die dem PHP-Code entspricht, entsprechend dem Codesegment im Binärprogramm
Literalspeicher: einige Anfangswerte der im PHP-Code definierten Variablen, der Name der aufgerufenen Funktion und der Klasse Namen, Konstantennamen usw. werden als Literale bezeichnet. Diese Werte werden zur Initialisierung von Variablen, Funktionsaufrufen usw. während der Ausführung verwendet.
Variablenzuordnung: Ähnlich wie bei Literalen bezieht sich darauf, wie viele Variablen und temporäre Variablen durch die aktuellen Opcodes definiert werden. Die Initialisierung wird durchgeführt, um zval auf einmal entsprechend der Gesamtzahl zuzuweisen , anstatt gemäß dem Variablennamenindex
Wie implementiert man den PHP-Code in den Opcode von?
Am einfachsten kann man sich das regelmäßige Matching vorstellen, aber so einfach ist der Prozess natürlich nicht. Der PHP-Kompilierungsprozess umfasst die lexikalische Analyse und die Syntaxanalyse, die mit re2c und bison durchgeführt werden. Die alte PHP-Version generiert direkt einen neuen abstrakten Syntaxbaum (AST). Das Opcode-Array wird generiert
Das obige ist der detaillierte Inhalt vonSo kompilieren Sie PHP-Dateien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!