Original? Mp. weixin. qq. coms? _ Getting started with extension development: Wu Feng ( e-commerce technology group) first learned about the overall architecture and operating mechanism of php before writing our first php extension. The php architecture is as follows:
Original? Http://mp.weixin.qq.com? _ Biz = MjM5MDg2NjIyMA = mid = 201705948idx = 1sn = f29d84635a6b03e586af6868b4f3c880 PHP: Wu Feng ( e-commerce technology group) before writing our first php extension, first, let's take a look at the overall php architecture and operating mechanism. The php architecture is as follows:
Original? Http://mp.weixin.qq.com? _ Biz = MjM5MDg2NjIyMA ==& mid = 201705948 & idx = 1 & sn = f29d84635a6b03e586af6868b4f3c880
PHP extension development
Author: Wu Feng (e-commerce technology group)
Before writing our first php extension, let's take a look at the overall architecture and operating mechanism of php.
The php architecture 1 is shown in. SAPI (server-side application programming port), which enables PHP to interact with other applications and abstract the complicated external environment, provides a set of fixed and unified interfaces for internal php, so that php itself is not affected by the external, and maintains a certain degree of independence. Common sapis include CGI, FastCGI, Shell CLI, apache mod_php5, and IIS isapis.
Another important thing is ZendEngine. Zend Engine is the core of PHP implementation officially provided. It provides language implementation infrastructure, and other well-known ones include facebook's hiphop implementation. For example, PHP syntax implementation, script compiling and running environment, expansion mechanism, and memory management. We will also be based on Zend Engine when writing php extensions later.
In the PHP3 era, the running mode of simultaneous interpretation and execution is still adopted, which is very inefficient. Second, the overall code coupling is relatively high, and the scalability is not good enough. Therefore, with the popularity of php in web application development, ZeevSuraski and Andi Gutmans decided to rewrite the code to solve these two problems. Finally, they named the core Engine of the technology Zend Engine.
The main feature of Zend Engine is to change the running mode of PHP side interpretation side execution to pre-Compile (Compile) and then Execute (Execute ). The separation of the two has brought a revolutionary change to PHP: The execution efficiency has been greatly improved. Due to the separation of functions, the coupling between modules is reduced, and the scalability is also greatly enhanced.
Currently, PHP implementation is closely related to Zend Engine. For example, many PHP extensions use Zend APIs, and Zend is the implementation of PHP, PHP only uses the Zend kernel to build the PHP language. Most PHP extensions use the Zend API, which causes many extensions of PHP to be coupled with the Zend engine, later, some PHP core developers proposed to solve this coupling problem. However, next we will write our first simple php Extension Based on Zend Engine.
1. Configuration File
Each PHP extension requires at least one configuration file and one source file. The configuration file is used to tell the Compiler which files should be compiled and to compile other library files required by this extension.
Create a new file in the ext directory of the php source code folder and use the extended name as myfirst. Create a config. m4 file in the directory and enter the following content:
PHP_ARG_ENABLE (
Myfirst,
[Whether to enable the "myfirst" extension],
[Enable-myfirst Enable "myfirst" extension support])
If test $ PHP_Myfirst! = "No"; then
PHP_SUBST (Myfirst_SHARED_LIBADD)
PHP_NEW_EXTENSION (myfirst, myfirst. c, $ ext_shared)
Fi
The above PHP_ARG_ENABLE function has three parameters. The first parameter is our extension (note that no quotation marks are required), and the second parameter is used when we run it. the content displayed in the/configure script. The last parameter is called. /configure-help. The PHP_SUBST function is only an encapsulation of the AC_SUBST function in autoconf by php. The PHP_NEW_EXTENSION function declares the extension name, the required source file name, and the extended compilation form. If the extension uses multiple files, you can list the file names in the function parameters, such as PHP_NEW_EXTENSION (sample, sample. c sample2.c sample3.c, $ ext_shared) the final $ ext_shared parameter is used to declare this extension as a dynamic library, which is dynamically loaded during php runtime.
2. Source File
After the configuration file is completed, the following are the header files and C files that have completed the expansion of the main logic.
Header file
// Php_myfirst.h
# Ifndef Myfirst_H
# Define Myfirst_H
// Load config. h. If configured
# Ifdef HAVE_CONFIG_H
# Include "config. h"
# Endif
// Load the php header file
# Include "php. h"
# Define phpext_myfirst_ptr & myfirst_module_entry
Extern zend_module_entrymyfirst_module_entry;
# Endif
C file
// Myfirst. c
# Include "php_myfirst.h"
// Module entry
Zend_module_entrymyfirst_module_entry = {
# If ZEND_MODULE_API_NO> = 20010901
STANDARD_MODULE_HEADER,
# Endif
"Myfirst", // extension name
NULL,/* Functions */
NULL,/* MINIT */
NULL,/* MSHUTDOWN */
NULL,/* RINIT */
NULL,/* RSHUTDOWN */
NULL,/* MINFO */
# If ZEND_MODULE_API_NO> = 20010901
"2.1", // extended version
# Endif
STANDARD_MODULE_PROPERTIES
};
# Ifdef COMPILE_DL_Myfirst
ZEND_GET_MODULE (myfirst)
# Endif
3. Extended Compilation
Prepare the source files to be compiled for the extension, and then compile them into the target file.
Step 1: Use phpize to generate a configure script, Makefile, and other files based on the config. m4 file:
$ Phpize
PHP Api Version: 20041225
Zend Module Api No: 20050617
Zend Extension Api No: 220050617
Now, you can view the directory where the extension is located. You will find that the phpize program generates many required php extension files, such as makefiles, based on the information in config. m4.
Part 2: run the./configure script and then execute make; make test. If there is no error, the extension target file myfirst will be generated under the module folder. so, because we have previously stated dynamic extensions in the configuration file, it will be compiled into a dynamic library.
Now, let's execute./buildconf-force under the root directory of the PHP source code, and then execute the./configure-help command. The myfirst extension information is displayed.
To enable PHP to find the desired extension file, we need to copy the compiled so file to the extension directory of PHP and configure it in php. ini:
Extension_dir =/usr/local/lib/php/modules/
Extension = myfirst. so
In this way, php will automatically load our extensions at each startup.
4. Compile extended functions
We have already generated an extension framework, but it does not have any practical effect. We also need to write specific functional functions.
# DefinePHP_FUNCTION ZEND_FUNCTION
# DefineZEND_FUNCTION (name) ZEND_NAMED_FUNCTION (ZEND_FN (name ))
# DefineZEND_NAMED_FUNCTION (name) void name (INTERNAL_FUNCTION_PARAMETERS)
# Define ZEND_FN (name) zif _ # name
Zif indicates zend internal function, and zif prefix indicates the name prefix of functions that can be called by PHP in C.
ZEND_FUNCTION (myfirst_hello)
{
Php_printf ("HelloWorld! \ N ");
}
The above function is expanded in a macro in C language as follows:
Voidzif_myfirst_hello (INTERNAL_FUNCTION_PARAMETERS)
{
Php_printf ("HelloWorld! \ N ");
}
The function has been implemented, but cannot be called in the program, because the function has not been registered in the extension module. Now let's take a look at zend_module_entry in the extension.
The value of/* Functions */In myfirst_module_entry (which is an important link between C extension and PHP language) is NULL, which is a function that has not been written before. Now we can assign the written function to it. The value must be of the zend_function_entry [] type:
Static zend_function_entrymyfirst_functions [] = {
ZEND_FE (myfirst_hello, NULL)
{NULL, NULL, NULL}
};
The last {NULL, NULL, NULL} is fixed. ZEND_FE () Macro function is a declaration of the myfirst_hello function. If there are multiple functions, you can directly add them to {NULL, NULL, NULL} in a similar form, note that you do not need to add a comma between each of them. After we make sure everything is correct, we replace the original members in zend_module_entry. Now it should be like this:
Z END_FUNCTION (myfirst_hello)
{
Php_printf ("HelloWorld! \ N ");
}
Static zend_function_entrymyfirst_functions [] = {
ZEND_FE (myfirst_hello, NULL)
{NULL, NULL, NULL}
};
Zend_module_entrymyfirst_module_entry = {
# If ZEND_MODULE_API_NO> = 20010901
STANDARD_MODULE_HEADER,
# Endif
"Myfirst", // extension name.
Myfirst_functions,/* Functions */
NULL,/* MINIT */
NULL,/* MSHUTDOWN */
NULL,/* RINIT */
NULL,/* RSHUTDOWN */
NULL,/* MINFO */
# If ZEND_MODULE_API_NO> = 20010901
"2.1", // This is our extended version.
# Endif
STANDARD_MODULE_PROPERTIES
};
In this way, we will complete a simple extension function, then re-configure, make, make test, and copy the. so file to the extension dir directory.
Finally, write a script to test it in the command line. You should be able to output helloworld.