PHP Interpreter Engine Execution flow
??? This introduces the process of executing a PHP script inside the engine, using the CLI SAPI as an example to introduce the core parts of the process, eliminating some initialization and cleanup operations.
??? CLI (command line Interface) that is PHP, this SAPI is installed by default, after we install PHP on the server, we usually generate an executable file, assuming this file is/usr/local/bin/php, Then we can execute a PHP script with the following command under the shell:
/usr/local/bin/php-f test.php
This command executes the test.php script in the current directory, and we do not care about the specifics of test.php, but only the internal process of the execution.
????? The main source code file of the CLI is in {PHPSRC}/SAPI/CLI/PHP_CLI.C, the whole process is executed from the main () function in this file, the whole function is long and can be divided into the following stages:
1: Parsing command-line arguments
2: Initializing the Environment
3: Compile and execute PHP code
4: Clean up the environment and return to exit
In the 1th phase, the parse-f parameter is to execute a PHP file, and the test.php after-F is the file that needs to be executed
Here we will focus on the 3rd phase, how to execute PHP code in test.php.
Finally, the PHP script is executed via Php_execute_script (&file_handle tsrmls_cc), which is defined in {PHPSRC}/MAIN/MAIN.C, the prototype is:
Phpapi int Php_execute_script (zend_file_handle *primary_file tsrmls_dc)?
The type of File_handle is Zend_file_handle, which is the Zend of a file handle, the contents of which are related to test.php.
Php_execute_script is ultimately called the zend_execute_scripts, which is defined in {PHPSRC}/ZEND/ZEND.C, the prototype is:
ZEND_API int zend_execute_scripts (int type tsrmls_dc, zval **retval, int file_count, ...)?
This function has variable parameters and can execute multiple PHP files at once, the most important of which is calling Zend_compile_file and Zend_execute,
Zend_compile_file is a function pointer declared in {phpsrc}/zend/zend_compile.c:
Zend_api Zend_op_array * (*zend_compile_file) (zend_file_handle *file_handle, int type tsrmls_dc);? When the engine is initialized, the address of the Compile_file function is assigned to the Zend_compile_file,compile_file function defined in {Phpsrc}/zend/zend_language_ SCANNER.C, you can see this function with the Zend_file_handle pointer as a parameter and return a pointer to Zend_op_array.
Zend_execute is also a function pointer, which is declared in {phpsrc}/zend/zend_execute.c:
zend_api extern void (*zend_execute) (Zend_op_array *op_array tsrmls_dc);?
Also at the time of engine initialization, the address of the Execute function is assigned to the definition of Zend_execute,execute at {phpsrc}/zend/zend_vm_execute.h.
By declaring that Zend_execute takes a pointer to the ZEND_OP_ARRAY structure as a parameter, the pointer is the return value of the previous zend_compile_file, and Zend_execute starts executing op code in Op_array, During the execution of OP code, various functions of the PHP language are implemented.
?
Here the main implementation work is basically done.
Ps:
??? Why do you define Zend_execute and zend_compile_file as function pointers?
??? When the engine is initialized (Zend_startup), the Zend_execute points to the default Execute,zend_compile_file pointing to the default compile_file. We can rewrite Zend_execute and zend_compile_file as other compile and execute functions before we actually compile and execute them, leaving hooks for our extension engine, such as a more famous extension VLD (http://) to view PHP's op code. WWW.DERICKRETHANS.NL/PROJECTS.HTML#VLD), this extension is the hook function (php_rinit_function) for each request initialization, Zend_execute and Zend_compile_ The file is replaced with its own vld_execute and vld_compile_file, which are actually encapsulated in the original function, adding additional functionality to the output opcode information, because the engine initialization occurs before the module request is initialized. and the module request initialization is also before compiling and executing, so such coverage can achieve the purpose.
?
?
Original address: http://blog.csdn.net/phpkernel/article/details/5716342