msgbartop
PHP源码分析,Zend引擎分析,Web相关技术研究,Web技术分享–左手代码 右手诗
msgbarbottom

12 Aug 08 PHP的函数(Introspecting PHP Function)

在PHP中,函数分为俩种,

  • 一种是zend_internal_function, 这种函数是由扩展或者Zend/PHP内核提供的,用’C/C++’编写的,可以直接执行的函数。
  • 另外一种是zend_user_function, 这种函数呢,就是我们经常在见的,用户在PHP脚本中定义的函数,这种函数最终会被ZE翻译成opcode array来执行
  • 查看zend_compile.h,我们可以找到如下的3个结构:


    typedef struct _zend_internal_function {
    /* Common elements */
    zend_uchar type;
    char * function_name;
    zend_class_entry *scope;
    zend_uint fn_flags;
    union _zend_function *prototype;
    zend_uint num_args;
    zend_uint required_num_args;
    zend_arg_info *arg_info;
    zend_bool pass_rest_by_reference;
    unsigned char return_reference;
    /* END of common elements */

    void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
    struct _zend_module_entry *module;
    } zend_internal_function;

    struct _zend_op_array {
    /* Common elements */
    zend_uchar type;
    char *function_name;
    zend_class_entry *scope;
    zend_uint fn_flags;
    union _zend_function *prototype;
    zend_uint num_args;
    zend_uint required_num_args;
    zend_arg_info *arg_info;
    zend_bool pass_rest_by_reference;
    unsigned char return_reference;
    /* END of common elements */

    zend_uint *refcount;

    zend_op *opcodes;
    zend_uint last, size;

    zend_compiled_variable *vars;
    int last_var, size_var;

    zend_uint T;

    zend_brk_cont_element *brk_cont_array;
    zend_uint last_brk_cont;
    zend_uint current_brk_cont;

    zend_try_catch_element *try_catch_array;
    int last_try_catch;

    /* static variables support */
    HashTable *static_variables;

    zend_op *start_op;
    int backpatch_count;

    zend_bool done_pass_two;
    zend_bool uses_this;

    char *filename;

    zend_uint line_start;
    zend_uint line_end;
    char *doc_comment;
    zend_uint doc_comment_len;

    void *reserved[ZEND_MAX_RESERVED_RESOURCES];
    };

    typedef union _zend_function {
    zend_uchar type; /* MUST be the first element of this struct! */

    struct {
    zend_uchar type; /* never used */
    char *function_name;
    zend_class_entry *scope;
    zend_uint fn_flags;
    union _zend_function *prototype;
    zend_uint num_args;
    zend_uint required_num_args;
    zend_arg_info *arg_info;
    zend_bool pass_rest_by_reference;
    unsigned char return_reference;
    } common;

    zend_op_array op_array;
    zend_internal_function internal_function;
    } zend_function;

    第一个结构,定义了zend_internal_function, 当PHP启动的时候 ,它会遍历每个载入的扩展模块,然后将模块中function_entry中指明的每一个函数, 创建一个zend_internal_function结构, 并将type置为ZEND_INTERNAL_FUNCTION(见下表), 将这个结构填入全局的函数表(一个HashTable);


    #define ZEND_INTERNAL_FUNCTION 1
    #define ZEND_USER_FUNCTION 2
    #define ZEND_OVERLOADED_FUNCTION 3
    #define ZEND_EVAL_CODE 4
    #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5

    第二个结构,op_array, 这个结构很重要, 因为:

          extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
       

    也就是说,我们编写的PHP脚本,都会被ZE翻译成op_array, 最后交由zend_execute执行。

    另外,在ZE中,用户定义的函数(userland function), 也会被翻译成一个op_array, 并填入全局函数表中。这个时候scope,function_name都不为空。而对于在全局作用域的直接代码来说,最后的op_array的scope为全局,function_name为空。

    第三个结构, 很有趣, 要理解这个结构,首先你要理解他的设计目标: zend_internal_function, zend_function,zend_op_array可以安全的互相转换(The are not identical structs, but all the elements that are in “common” they hold in common, thus the can safely be casted to each other);

    具体来说,当在op code中通过ZEND_DO_FCALL调用一个函数的时候,ZE会在函数表中,根据名字(其实是lowercase的函数名字,这也就是为什么PHP的函数名是大小写不敏感的)查找函数, 如果找到,返回一个zend_function结构的指针(仔细看这个上面的zend_function结构), 然后判断type,如果是ZEND_INTERNAL_FUNCTION, 那么ZE就调用zend_execute_internal,通过zend_internal_function.handler来执行这个函数, 如果不是,就调用zend_execute来执行这个函数包含的zend_op_array.

    Related Posts:

    Tags: , ,

    Reader's Comments

    1. |

      留言:Brett Anderson很帅

    2. |

      ….., 相关度为0的留言

    3. |

      学习了,期待下一篇

    4. |

      em… chinese?

    5. |

      Love Epicentre is one of the most popular online dating sites, and has a huge member database with thousands of free profiles to browse. It is a trusted and safe online dating site that caters to long term relationship seekers and finds your match based on personality traits.

    Leave a Comment

    *
    To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
    Click to hear an audio file of the anti-spam word