After reading some of the content in the preface, you should have a general understanding of PHP extension development. Some people may think that development expansion is very complicated and complicated. In fact, this is not the case, in this article, we quickly enter the role and develop our first extension.
I. Compile PHP
Before development, you need to prepare the PHP source code and compile it. The process is as follows:
-zxvf php-..-.
I used php5.3.9. After decompression, we entered the PHP source code directory, and then we directly compiled and added php. ini:
./configure --prefix=/usr/local/webserver/php --enable-fastcgi --enable-fpm --enable- && /home/soft/php-./php.ini-development /usr/local/webserver/php/lib/php.ini
After compilation is complete, I have not statically compiled other extensions, But I have enabled debug, which will be used later. Modify the corresponding items in php. ini. I will not go into detail here.
Now we can add PHP-related environment variables to save a lot of work:
vim /root/.bash_profile
I use root, and other users modify the contents in the corresponding user directory. in the bask_profile file, add/usr/local/webserver/php/bin/after the PATH in the file, as shown below:
PATH=$PATH:$HOME/bin:/usr/local/webserver/php/bin/
After the environment variables are set, let's check the PHP version:
OK. The compilation is complete. Let's continue.
2. Typical Development Process
A typical extended development process is as follows:
3. Define extended functions
-2147483648 to 2147483647, same as 32-bit systems.
Iv. Formal Development
cd /home/soft/php-./ext
Next, let's take a look at the PHP extension skeleton tool ext_skel to generate a skeleton. The usage of ext_skel is as follows:
. /Ext_skel -- extname = module [-- proto =] [-- stubs =] [-- xml [= -- skel =] [-- full-xml] [-- no --- extname = -- proto = -- stubs = generate only stubs -- xml generate xml documentation to be added to phpdoc --- skel = path to the skeleton directory (set the directory generated by the skeleton, if this item is not set, all help comments are displayed in ext/-- full-xml generate xml documentation a self --- no-help don and helper functions to test the module compiled by default.)
This time, we will use two options: -- extname = myip, which defines the extension name, And -- proto = myip. pro, which defines the extension function prototype. First, we will generate the extension function prototype file:
vim myip.pro
Add the following content:
ip2long32( ip)
This means that there is a function in our extension. The return value is int type and the input value is string.
Run the following command to generate the extension SKELETON:
./ext_skel --extname=myip --proto=myip.pro
OK. At this time, you will find that a sub-directory myip is generated under the current PHP extension directory. Go to myip and check it:
You will find that a bunch of files are generated, such:
Now we can proceed to step 2.
2. Modify config. m4
For more information about the functions of the config. m4 file, refer to the subsequent articles for details.
Use vim to edit config. m4:
vim config.m4
Remove the dnl at the beginning of Lines 16 to 18, as shown below:
The specific reason for this is described in the following article. Here we exit and save config. m4 and continue to the next step.
3. Encoding
Let's cheer up!
vim myip.c
Find the following location:
The figure below shows the corresponding functions generated by the extension skeleton tool based on the function prototype we provide. Here are several notes:
1. PHP_FUNCTION: a macro defined by the PHP core. It is the same as ZEND_FUNCTION and is used to define extended functions. The actually generated function name is zif_ip2long32.
2. zend_parse_parameters: Because PHP is a weak type language and C is a strong type, you need to use this function to receive parameters passed in by PHP and perform type conversion, convert the PHP variable to a recognizable type in C.
The prototype of the zend_parse_parameters function is as follows:
zend_parse_parameters( num_args TSRMLS_CC, *type_spec, …);
Parameter description:
- Num_args: number of parameters passed to the function. Generally, the macro ZEND_NUM_ARGS () is used ().
- TSRMLS_CC: thread security, always passing the TSRMLS_CC macro. Details: http://www.54chen.com/php-tech/what-is-tsrmls_cc.html
- Type_spec: The third parameter is a string that specifies the expected parameter type of the function.
- ...: List of variables that need to be updated with parameter values]
Type_spec is a formatted string. Its common meanings are as follows:Parameter represents the typeb BooleanL IntegerD Floating pointS StringR ResourceA ArrayO Object instance ObjectO Object instance of a specified type Object of a specific typeZ Non-specific zval of any type ~Z zval ** typeF indicates the function and method name.
Modify the function as follows:
*ip = argc = (zend_parse_parameters(argc TSRMLS_CC, , &ip, &ip_len) ==, &ip1, &ip2, &ip3, &= (int32_t)((ip1 << ) | (ip2 << ) | (ip3 << ) |
The function is complete. Here there is a special RETURN_LONG (ip_int32), which is also a macro provided by the PHP kernel for returning values to PHP. The details are as follows:
Set the return value and end the function. Set the return value macro return type and parameters.
RETURN_LONG (l) RETVAL_LONG (l) Integer
RETURN_BOOL (B) RETVAL_BOOL (B) Boolean (1 or 0)
RETURN_NULL () RETVAL_NULL () NULL
RETURN_DOUBLE (d) RETVAL_DOUBLE (d) floating point number
RETURN_STRING (s, dup) RETVAL_STRING (s, dup) string. If dup is 1, the engine will call estrdup () to duplicate s and use copy. If dup is 0, s is used.
RETURN_STRINGL (s, l, dup) RETVAL_STRINGL (s, l, dup) is a string value of l. Similar to the previous macro, but the speed is faster because the length of s is specified.
RETURN_TRUE RETVAL_TRUE returns a Boolean value of true. Note that this macro has no parentheses.
RETURN_FALSE RETVAL_FALSE returns the Boolean value false. Note that this macro has no parentheses.
RETURN_RESOURCE (r) RETVAL_RESOURCE (r) Resource handle.
After encoding is complete, save and exit. Then we can start compiling.
4. Compile
/configure --with-php-config=/usr/local/webserver/php/bin/php- &&
If the compilation is complete, the following prompt will be displayed:
Installing shared extensions: /usr/local/webserver/php/lib/php/extensions/debug-non-zts-/
Go to the directory and check whether myip. so exists. If yes, we can modify php. ini to load the so file.
5. Modify php. ini
cd /usr/local/webserver/php/
Modify extension_dir and add extension = myip. so
extension_dir = "/usr/local/webserver/php/lib/php/extensions/debug-non-zts-20090626/"= myip.so
Exit save and restart php. If Phpfpm is used, run the following command:
-USR2 ` /usr/local/webserver/php/var/run/php-fpm.pid`
Check whether the extension is loaded normally:
[root@tm977 lib]# php -m|
It indicates that it has been loaded normally. Finally, let's test the extended function!
6. Test
php -r (--r ()
As shown above, ip2long32 outputs 32-bit signed integers, while ip2long outputs 64-bit unsigned integers!
V. Summary