Maison >développement back-end >tutoriel php >Comment compiler des fichiers php
PHP est un langage analytique de haut niveau. En fait, du point de vue du noyau Zend, PHP est un programme C ordinaire. Il a une fonction principale. Le code PHP que nous écrivons est l'entrée de ce programme. le noyau traite le résultat de sortie, le processus dans lequel le noyau "traduit" le code PHP en un programme C reconnaissable est la compilation de PHP.
Cours recommandé : Tutoriel PHP
Le programme C compile une ligne de code en code machine lors de la compilation, et chaque opération est considérée comme une instruction machine, ces instructions sont écrites dans le programme binaire compilé Lors de l'exécution, le programme binaire est chargé dans la zone mémoire correspondante (zone constante, zone de données, zone de code), la pile en cours d'exécution est allouée, puis repart du code. Zone.Commencez l'exécution à partir de la position de départ. Il s'agit d'un processus simple de compilation et d'exécution de programme C.
De même, la compilation de PHP est similaire à celle des programmes C ordinaires, sauf que le code PHP n'est pas compilé en code machine, mais est analysé en plusieurs tableaux d'opcodes. Chaque opcode est une structure ordinaire en C, et sa signification correspond à C Le processus d'exécution des instructions machine du programme est que le moteur exécute les opcodes en séquence. Par exemple, si nous définissons une variable en PHP : $a = 123;
, l'exécution finale dans le noyau consiste à mallocer un. morceau de mémoire, puis écrivez-y la valeur.
Dans le fichier zend_compile.h, la structure de l'opcode :
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; //返回值类型 };
La tâche du processus d'analyse de PHP est donc de convertir le code PHP (via l'analyse lexicale re2c, l'analyse syntaxique bison) en un opcode tableau, dans le code Toutes les informations sont stockées dans l'opcode, puis le tableau d'opcode est transmis au moteur zend pour exécution. L'opcode est la commande spécifique exécutée par le noyau, telle que les opérations d'affectation, d'addition et de soustraction, la fonction. appels, etc. Chaque opcode correspond à un handle de traitement. Ces gestionnaires sont des fonctions C définies à l’avance.
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]; };
Instruction opcode : l'action de traitement spécifique correspondant au code PHP, correspondant au segment de code dans le programme binaire
Stockage littéral : quelques valeurs initiales des variables définies dans le code PHP, le nom de la fonction appelée, et les noms de classe, les noms de constantes, etc. sont appelés littéraux. Ces valeurs sont utilisées pour initialiser les variables, les appels de fonction, etc. lors de l'exécution
Allocation de variable : similaire aux littéraux, ceci. fait référence au nombre de variables et de variables temporaires définies par les opcodes actuels, chaque variable a un numéro correspondant. L'initialisation est effectuée pour allouer zval en une seule fois en fonction du nombre total. Lorsqu'elle est utilisée, elle est également indexée en fonction du nombre. , plutôt que selon l'index du nom de la variable
Comment implémenter du code PHP vers l'opcode de ?
La façon la plus simple de penser est une correspondance régulière, mais bien sûr, le processus n'est pas si simple. Le processus de compilation PHP comprend une analyse lexicale et une analyse syntaxique, qui sont complétées à l'aide de re2c et bison. L'ancienne version de PHP génère directement un opcode (AST). L'AST est généré lors de l'étape d'analyse syntaxique, puis l'opcode. Le tableau d'opcodes est généré
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!