引荐课程:PHP教程。
C顺序在编译时将一行行代码编译为机械码,每一个操纵都认为是一条机械指令,这些指令写入到编译后的二进制顺序中,实行的时刻将二进制顺序load进响应的内存地区(常量区、数据区、代码区)、分派运行栈,然后从代码区肇端位置最先实行,这是C顺序编译、实行的简朴历程。
一样,PHP的编译与一般的C顺序相似,只是PHP代码没有编译成机械码,而是剖析成了若干条opcode数组,每条opcode就是C内里一般的struct,寄义对应C顺序的机械指令,实行的历程就是引擎顺次实行opcode,比方我们在PHP里定义一个变量:$a = 123;
,终究到内核里实行就是malloc一块内存,然后把值写进去。
在zend_compile.h文件中,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; //返回值范例 };
所以PHP的剖析历程使命就是将PHP代码(经由过程词法剖析re2c,语法剖析bison)转化为opcode数组,代码里的一切信息都保存在opcode中,然后将opcode数组交给zend引擎实行,opcode就是内核细致实行的敕令,比方赋值、加减操纵、函数挪用等,每一条opcode都对应一个处置惩罚handle,这些handler是提早定义好的C函数。
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指令:即PHP代码细致对应的处置惩罚行动,与二进制顺序中的代码段对应
字面量存储:PHP代码中定义的一些变量初始值、挪用的函数称号、类称号、常量称号等等称之为字面量,这些值用于实行时初始化变量、函数挪用等等
变量分派情况:与字面量相似,这里指的是当前opcodes定义了若干变量、暂时变量,每一个变量都有一个对应的编号,实行初始化依据总的数量一次性分派zval,运用时也完整依据编号索引,而不是依据变量名索引
从PHP代码到opcode是怎样完成的?
最轻易想到的体式格局就是正则婚配,固然历程没有这么简朴。PHP编译历程包含词法剖析、语法剖析,运用re2c、bison完成,旧的PHP版本直接生成了opcode,PHP7新增了笼统语法树(AST),在语法剖析阶段生成AST,然后再生成opcode数组
以上就是怎样编译php文件的细致内容,更多请关注ki4网别的相干文章!