Home  >  Article  >  Backend Development  >  How to compile php files

How to compile php files

(*-*)浩
(*-*)浩Original
2019-05-11 16:52:558239browse

PHP is an analytical high-level language. In fact, from the perspective of the Zend kernel, PHP is an ordinary C program. It has a main function. The PHP code we write is the input of this program, and then the kernel processes and outputs the results. , the process in which the kernel "translates" the PHP code into a C program that can be recognized is the compilation of PHP.

Recommended course: PHP tutorial

How to compile php files

C program compiles line of code into machine code during compilation, and each operation Considered as a machine instruction, these instructions are written into the compiled binary program. During execution, the binary program is loaded into the corresponding memory area (constant area, data area, code area), the running stack is allocated, and then starts from the code area. Start execution from the starting position. This is a simple process of C program compilation and execution.

Similarly, the compilation of PHP is similar to that of ordinary C programs, except that the PHP code is not compiled into machine code, but is parsed into several opcode arrays. Each opcode is an ordinary struct in C, and its meaning corresponds to C The execution process of the machine instructions of the program is that the engine executes the opcode in sequence. For example, we define a variable in PHP: $a = 123;. The final execution in the kernel is to malloc a piece of memory and then write the value into it. .

In the zend_compile.h file, the opcode structure:

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; //返回值类型
};

So the task of PHP's parsing process is to convert the PHP code (through lexical analysis re2c, syntax analysis bison) into an opcode array, in the code All the information is stored in the opcode, and then the opcode array is handed over to the zend engine for execution. The opcode is the specific command executed by the kernel, such as assignment, addition and subtraction operations, function calls, etc. Each opcode corresponds to a processing handle. These handlers are C functions defined in advance.

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 instruction: that is, the specific processing action corresponding to the PHP code, corresponding to the code segment in the binary program
Literal storage: some initial values ​​of variables defined in the PHP code, the name of the called function, and the class Names, constant names, etc. are called literals. These values ​​are used to initialize variables, function calls, etc. during execution.
Variable allocation: similar to literals, this refers to how many variables and temporary variables are defined by the current opcodes , each variable has a corresponding number. The initialization is performed to allocate zval at one time according to the total number. When used, it is also indexed according to the number, rather than according to the variable name index.

How to implement from PHP code to opcode of?

The easiest way to think of is regular matching, but of course the process is not that simple. The PHP compilation process includes lexical analysis and syntax analysis, which are completed using re2c and bison. The old PHP version directly generates opcode. PHP7 adds a new abstract syntax tree (AST). The AST is generated during the syntax analysis stage, and then the opcode array is generated

The above is the detailed content of How to compile php files. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn