


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 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
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> };
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>
*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>
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>
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>);
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
Internal function
print_r(<span>'</span><span>i am print_r function.</span><span>'</span>);
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>
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>
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.

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

What are the magic methods of PHP? PHP's magic methods include: 1.\_\_construct, used to initialize objects; 2.\_\_destruct, used to clean up resources; 3.\_\_call, handle non-existent method calls; 4.\_\_get, implement dynamic attribute access; 5.\_\_set, implement dynamic attribute settings. These methods are automatically called in certain situations, improving code flexibility and efficiency.
