旗下导航:搜·么
当前位置:网站首页 > PHP教程 > 正文

怎样编译php文件【php教程】,php

作者:搜教程发布时间:2019-12-01分类:PHP教程浏览:43评论:0


导读:PHP是剖析型高等言语,事实上从Zend内核的角度来看PHP就是一个一般的C顺序,它有main函数,我们写的PHP代码是这个顺序的输入,然后经由内核的处置惩罚输出效果,内核将PHP...
PHP是剖析型高等言语,事实上从Zend内核的角度来看PHP就是一个一般的C顺序,它有main函数,我们写的PHP代码是这个顺序的输入,然后经由内核的处置惩罚输出效果,内核将PHP代码"翻译"为C顺序可辨认的历程就是PHP的编译。

引荐课程: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网别的相干文章!

标签:php


欢迎 发表评论: