Home > Backend Development > PHP Tutorial > In-depth understanding of the internal structure of the PHP kernel (5) function, in-depth understanding of the internal structure_PHP tutorial

In-depth understanding of the internal structure of the PHP kernel (5) function, in-depth understanding of the internal structure_PHP tutorial

WBOY
Release: 2016-07-12 08:59:12
Original
821 people have browsed it

In-depth understanding of the internal structure of PHP kernel (5) functions, in-depth understanding of the internal structure

PHP functions include user-defined functions, internal functions (print_r count...), Anonymous function, variable function ($func = 'print_r'; $func(array('a','b'));)

The functions in the PHP kernel source code are divided into the following types

<span>#define</span> ZEND_INTERNAL_FUNCTION              1
<span>#define</span> ZEND_USER_FUNCTION                  2  
<span>#define</span> ZEND_OVERLOADED_FUNCTION            3
<span>#define</span> ZEND_EVAL_CODE                      4
<span>#define</span> ZEND_OVERLOADED_FUNCTION_TEMPORARY  5
Copy after login

1. User function (ZEND_USER_FUNCTION)

Functions do not necessarily have an explicit return value. In PHP implementation, even if there is no explicit return, the PHP kernel will return NULL for us.

During the execution process of ZEND, runtime information will be stored in _zend_execute_data:

<span>struct</span><span> _zend_execute_data {
    </span><span>//</span><span>...省略部分代码</span>
<span>    zend_function_state function_state;
    zend_function </span>*fbc; <span>/*</span><span> Function Being Called </span><span>*/</span>
    <span>//</span><span>...省略部分代码</span>
};
Copy after login

During the program initialization process, function_state will also be initialized. Function_state consists of two parts:

typedef <span>struct</span><span> _zend_function_state {
    zend_function </span>*<span>function;
    </span><span>void</span> **<span>arguments;
} zend_function_state;</span>
Copy after login

*arguments is a pointer to function parameters, and the function body is stored in *function. *function is a zend_function structure, which ultimately stores all the information of the user-defined function. The specific structure is as follows:

<span>typedef union _zend_function {
    zend_uchar type;    </span><span>/*</span><span> MUST be the first element of this struct! </span><span>*/</span>
 
    <span>struct</span><span> {
        zend_uchar type;  </span><span>/*</span><span> never used </span><span>*/</span>
        <span>char</span> *function_name;    <span>//</span><span>函数名称</span>
        zend_class_entry *scope; <span>//</span><span>函数所在的类作用域</span>
        zend_uint fn_flags;     <span>//</span><span>函数类型,如用户自定义则为 #define </span>
ZEND_USER_FUNCTION <span>2</span><span>  
        union _zend_function </span>*prototype; <span>//</span><span>函数原型</span>
        zend_uint num_args;     <span>//</span><span>参数数目</span>
        zend_uint required_num_args; <span>//</span><span>需要的参数数目</span>
        zend_arg_info *arg_info;  <span>//</span><span>参数信息指针</span>
<span>        zend_bool pass_rest_by_reference;
        unsigned </span><span>char</span> return_reference;  <span>//</span><span>返回值</span>
<span>    } common;
 
    zend_op_array op_array;   </span><span>//</span><span>函数中的操作</span>
<span>‰
    zend_internal_function internal_function;  
} zend_function;</span>
Copy after login

The op_array in the zend_function structure stores all the operations in the function. When the function is called, ZEND will execute the oplines in the op_array sequentially one by one and return the final result. The definition and execution of functions are separated, and a function can exist as an independent running unit.

2. Internal function (ZEND_INTERNAL_FUNCTION)

The ZEND_INTERNAL_FUNCTION function is provided by the extension or the Zend/PHP kernel. It is written in c/c and can be executed directly. The following is the structure of the internal function

typedef <span>struct</span><span> _zend_internal_function {
    </span><span>/*</span><span> Common elements </span><span>*/</span><span>
    zend_uchar type;
    </span><span>char</span> *<span> function_name;
    zend_class_entry </span>*<span>scope;
    zend_uint fn_flags;
    union _zend_function </span>*<span>prototype;
    zend_uint num_args;
    zend_uint required_num_args;
    zend_arg_info </span>*<span>arg_info;
    zend_bool pass_rest_by_reference;
    unsigned </span><span>char</span><span> return_reference;
    </span><span>/*</span><span> END of common elements </span><span>*/</span>
 
    <span>void</span> (*<span>handler)(INTERNAL_FUNCTION_PARAMETERS);
    </span><span>struct</span> _zend_module_entry *<span>module;
} zend_internal_function;</span>
Copy after login

During module initialization, ZE will traverse each loaded extension module, and then create a zend_internal_function structure for each function (module->functions) specified in function_entry in the module, and set its type to ZEND_INTERNAL_FUNCTION, fill this structure into the global function table (HashTable structure); for the function setting and registration process, see the zend_register_function function in the Zend/zene_API.c file. In addition to processing the function page, this function also processes class methods, including those magic methods.

The structure of the internal function is basically similar to the structure of the user-defined function, with some differences:

  • Invoking method, handler field, if it is ZEND_INTERNAL_FUNCTION, then ZEND will call zend_execute_internal and execute this function through zend_internal_function.handler. The user-defined function needs to generate intermediate code, and then map the intermediate code to the corresponding method to call it.
  • The built-in function has an additional module field in the structure, indicating which module it belongs to. Different extension modules are different
  • Type field. In user-defined functions, the type field is almost useless, while the type field in built-in functions serves as a distinction between several internal functions.

3. Variable function

If there are parentheses after a variable name, PHP will look for a function with the same name as the value of the variable and try to execute it.

Variable function $func

$func = <span>'</span><span>print_r</span><span>'</span><span>;
$func(</span><span>'</span><span>i am print_r function.</span><span>'</span>);
Copy after login

Compiled intermediate code

function name:  (<span>null</span><span>)
number of ops:  </span><span>9</span><span>
compiled vars:  </span>!<span>0</span> =<span> $func
line     # </span>*  op                           fetch          ext  <span>return</span><span> operands
</span>------------------------------------------------------------------------------
-
-
   <span>2</span>     <span>0</span>  ><span>   EXT_STMT
         </span><span>1</span>      ASSIGN                                                   !<span>0</span><span>, 
</span><span>'</span><span>print_r</span><span>'</span>
   <span>3</span>     <span>2</span><span>      EXT_STMT
         </span><span>3</span>      INIT_FCALL_BY_NAME                                       !<span>0</span>
         <span>4</span><span>      EXT_FCALL_BEGIN
         </span><span>5</span><span>      SEND_VAL                                                 
</span><span>'</span><span>i+am+print_r+function.</span><span>'</span>
         <span>6</span>      DO_FCALL_BY_NAME                              <span>1</span>
         <span>7</span><span>      EXT_FCALL_END
         </span><span>8</span>    > RETURN                                  1
Copy after login

Internal function

print_r(<span>'</span><span>i am print_r function.</span><span>'</span>);
Copy after login

Compiled intermediate code

function name:  (<span>null</span><span>)
number of ops:  </span><span>6</span><span>
compiled vars:  none
line     # </span>*  op                           fetch          ext  <span>return</span><span>  operands
</span>-------------------------------------------------------------------------------
-
-
   <span>2</span>     <span>0</span>  ><span>   EXT_STMT
         </span><span>1</span><span>      EXT_FCALL_BEGIN
         </span><span>2</span><span>      SEND_VAL                                                 
</span><span>'</span><span>i+am+print_r+function.</span><span>'</span>
         <span>3</span>      DO_FCALL                                      <span>1</span>          
<span>'</span><span>print_r</span><span>'</span>
         <span>4</span><span>      EXT_FCALL_END
         </span><span>5</span>    > RETURN                                                   <span>1</span>
Copy after login

Comparison shows that there are some differences between the two in calling the intermediate code. The variable function is DO_FCALL_BY_NAME, while the internal function is DO_FCALL. This has already been decided during syntax parsing. See part of the code in the zend_do_end_function_call function in the Zend/zend_complie.c file:

<span>if</span> (!is_method && !is_dynamic_fcall && function_name->op_type==<span>IS_CONST) {
        opline</span>->opcode =<span> ZEND_DO_FCALL;
        opline</span>->op1 = *<span>function_name;
        ZVAL_LONG(</span>&opline-><span>op2.u.constant, 
zend_hash_func(Z_STRVAL(function_name</span>->u.constant), Z_STRLEN(function_name-
>u.constant) + <span>1</span><span>));
    } </span><span>else</span><span> {
        opline</span>->opcode =<span> ZEND_DO_FCALL_BY_NAME;
        SET_UNUSED(opline</span>-><span>op1);
    }</span>
Copy after login

If it is not a method and is not called dynamically, and the function name is a string variable, the intermediate code generated is ZEND_DO_FCALL. Otherwise it is ZEND_DO_FCALL_BY_NAME. In addition, the variable function is used as a callback function, and its processing process is in the zend_do_pass_param function of the Zend/zend_complie.c file, which will eventually be reflected in ZEND_SEND_VAL_SPEC_CONST_HADNLER and other functions during the execution of the intermediate code.

4. Anonymous functions

Anonymous function is a type of function or subroutine that can be called without specifying an identifier. Anonymous functions can be conveniently passed as parameters to other functions.

 

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/1099824.htmlTechArticleIn-depth understanding of the internal structure of PHP kernel (5) functions, in-depth understanding of the internal structure of PHP functions including user-defined functions , internal function (print_r count...), anonymous function, variable function ($f...
Related labels:
php
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template