Use C to expand PHP
Keywords: PhP Extension
Environment requirements: Linux and GCC
First, we should choose how to build our extension modules in three ways:
1. External modules
External modules are compiled into shared libraries and loaded dynamically using the DL () function.
Benefits: (1) PHP does not need to be re-compiled (2) PHP is small in size, because it does not need to be compiled into PHP
Disadvantages: (1) Every execution of *. php scripts requires DL (), which is less efficient.
(2) Call DL () every time ()
2. Built-in Modules
Compile to PhP
Benefits: (1) the module can be directly used in the PHP script without dynamic loading.
(2) You do not need to compile the module into A. So shared library because it is directly compiled into PHP.
Disadvantages: (1) PHP needs to be re-compiled for module changes
(2) The PHP binary file is large because it is compiled into PHP and occupies more memory.
3. the Zend Engine
Zend core implementation (for details, see Zend API)
Note: We recommend that you use 2nd methods to directly compile the program into PHP. However, in the following example, we compile the program into an external module.
Because, external modules do not need to re-compile PHP, so in the test phase, first compile into a shared library, and then use DL ()
Load (but remember to set the security mode to off in PHP. INI). After the test, recompile it into PHP in 2nd ways.
1. Download the PHP source code and decompress it. Then we start to build the code structure. We can use the ext_skel program provided in the ext directory of the PHP source code package to generate the structure we need.
[Ext] #./ext_skel -- extname = haosoft_php_module
This will generate a haosoft_php_module directory under Ext.
The directory contains several files, such as config. M4, haosoft_php_module.h, and haosoft_php_module.c.
2. haosoft_php_module.h is the module header file (familiar with the C language). Open it with VI and delete one of the lines:
Php_function (confirm_myext_compiled);/* for testing, remove later .*/
Changed:
Php_function (haosoft_test);/* for testing, remove later .*/
Note:
Php_function () is a Zend macro. It is known as a C function and is available in PHP scripts. The parameter is the name of the function. The example function here is haosoft_test.
3. haosoft_php_module.c is the main file, which contains the implementation. When VI is opened, we delete it.
Php_function (confirm_myext_compiled)
{
Char * Arg = NULL;
Int arg_len, Len;
Char string [256];
If (zend_parse_parameters (zend_num_args () tsrmls_cc, "S", & Arg, & arg_len) = failure ){
Return;
}
Len = sprintf (string, "Congratulations! You have successfully modified EXT/%. 78 s/config. M4. module %. 78 s is now compiled into PHP. "," haosoft_php_module ", ARG );
Return_stringl (string, Len, 1 );
}
Added:
Php_function (haosoft_test ){
Zend_printf ("this is my PHP module! ");
}
4. Now, let's compile our module. Because we want to compile it into so, we choose to compile it manually.
Go to the ext directory:
Start compiling and compile it into *. O object file. Pay attention to this "-dcompile_dl_haosoft_php_module ",
In haosoft_php_module.c, you can find the following statement:
# Ifdef compile_dl_haosoft_php_module
Zend_get_module (haosoft_php_module)
# Endif
Haosoft_php_module is an upper-case Module name. You can replace it with another name, but this preprocessing constant must be consistent
The preceding statement is consistent. As for the zend_get_module (haosoft_php_module) of the preceding statement, we will
Chapter to explain its meaning.
[Ext] # cc-FPIC-dcompile_dl_haosoft_php_module = 1-I/usr/local/include-I. -I .. /Main-I .. -I .. /tsrm-I .. /Zend-c-o haosoft_php_module/haosoft_php_module.o haosoft_php_module/haosoft_php_module.c
After execution, a haosoft_php_module.o file is generated in the directory, and then connected:
[Ext] # cc-shared-L/usr/local/lib-rdynamic-O haosoft_php_module/haosoft_php_module.so haosoft_php_module/haosoft_php_module.o
The haosoft_php_module.so file is generated in the directory.
Then we need to create a directory
[Ext] # mkdir-P/usr/local/PHP/lib/PHP/extensions/no-debug-non-zts-20041030
The above 20041030 number is the Zend internal module API number, if you do not know, you first create a PHP File
Parts:
Test. php
DL ("ABC. So ");
?>
If you run the file in a browser, an error message is displayed. You can obtain this number in the error message. Change the path according to the number and your PHP installation directory.
After creating the directory, move haosoft_php_module.so to the directory you just created.
[Ext] # mv haosoft_php_module/haosoft_php_module.so/usr/local/PHP/lib/PHP/extensions/no-debug-non-zts-20041030
OK! We can test the created module. Currently, the module only has a haosoft_test () non-parameter method.
Create a PHP file:
Test. php
// Load the created Module
DL ("haosoft_php_module.so ");
// Call a function
Haosoft_test ();
?>
Run. "This is my module!" is displayed! ?
5. After the module is compiled and tested correctly, we can compile it into PHP and return to the PHP source code package root directory.
Run:
[Php-5.0.6] #./buildconf -- force
[Php-5.0.6] #./configure -- enable-haosoft_php_module... maybe you have other options
# Make
[Php-5.0.6] # make install
[Php-5.0.6] # sh/etc/init. d/httpd restart... restart Apache
---------------------------------------------------------------
This example is compiled on php5.0.6. In the next chapter, we will analyze the content in the files haosoft_php_module.h and haosoft_php_module.c, as well as the definition and use of parameters and return functions.
It's time to go to bed! Write down another chapter if you have time. I hope the above content will be helpful to you!
In the previous chapter, I used C to expand PHP (1 ).
How to write your own functions, next we will start to write a function with Parameters
Extended functions with returned values.
Because Zend does not support formal function call syntax checks, we must be "careful" when writing extended functions, that is, we must strictly check the validity of calls. First, let's write a function:
# Include "string. H"
Php_function (haosoft_strcat ){
Char * pc_arg_one = NULL;
Char * pc_arg_tow = NULL;
Long arg_one_len;
Long arg_tow_len;
If (zend_parse_parameters (zend_num_args () tsrmls_cc, "SS", & pc_arg_one, & arg_one_len, & pc_arg_tow, & arg_tow_len) = failure ){
Return;
}
Return_stringl (strcat (pc_arg_one, pc_arg_tow), (arg_one_len + arg_tow_len), 1 );
}
Let's analyze this function:
1.
If (zend_parse_parameters (zend_num_args () tsrmls_cc, "SS", & pc_arg_one, & arg_one_len, & pc_arg_tow, & arg_tow_len) = failure ){
Return;
}
This is the statement for checking parameters and obtaining parameters. zend_parse_parameters () is an API function provided by Zend. The first parameter is the number of parameters. You can use zend_num_args () provided by Zend () tsrmls_cc is required. The third parameter "SS" specifies the parameter Type (s-string). This function has two string parameters, so it is "SS ", the following parameter is the parameter value you want to obtain. Note that if the parameter type is "S", a long will be passed after the parameter value to obtain the length of the string. if the zend_parse_parameters function is successful, return
Success. If it fails, failure is returned and an error message is output.
2.
Return_stringl (strcat (pc_arg_one, pc_arg_tow), (arg_one_len + arg_tow_len), 1 );
The purpose of this statement is to return a value. return_stringl () is the returned string. For more information, see the Zend api reference manual. This clause concatenates two string parameters and returns the result.
----------------------------------------------------------
After compiling the extension module, we can call this function in PHP.
<? PHP
$ S_result = haosoft_strcat ("A", "B ");
Echo $ s_result;
?>
Output: AB
---------------------------------------------------
Note:
The sequence table is specified for the function parameter type, and some functions that return the function return values can be found in the Zend document, which is not listed here.
Due to incomplete Zend API instructions, many macro and most Zend API functions are not described in detail.
I checked some Zend documents and wrote some PHP extensions using C ++. I think it is really troublesome.
Only one class of myclass: getstring () method must be implemented in PHP.
<? PHP
$ OBJ = new myclass ();
$ String = $ obj-> getstring ();
?>
I have written hundreds of lines of code, which is a nightmare for people who are used to object-oriented programming. I hope Zend can be improved in this regard, when I have time, I will write about how to use C ++ to write PHP extensions.
To be continued...
The last two chapters describe the basic usage of the extension module. I believe that you can build your own extension module. Next, let's take a look at several important functions:
1. php_minit_function (mymodule );
After the module is loaded by Zend engine (ze), for example, when Apache is started and the PHP module is loaded, ze will call this function for each extension module (if any ), you can perform initialization operations in this function.
2. php_rinit_function (mymodule );
For every PHP script request that "uses" this module, execute this function (if any). The best example is the session extension module. If you execute the session in a PHP script. start (), php_rinit_function () of the session module will be called. for more information, see the source code of the session module.
3. php_rshutdown_function (mymodule );
Unlike php_rinit_function (), this function is executed after a PHP script is executed.
4. php_mshutdown_function (mymodule );
After ze receives the Shutdown signal, such as Apache uninstalling the PHP module, ze calls this function for each module and closes its core subsystem.
-------------------------------------------------------
How to use the above functions?
First, declare in the header file ("mymodule. H:
Php_minit_function (mymodule );
Php_mshutdown_function (mymodule );
Php_rinit_function (mymodule );
Php_rshutdown_function (mymodule );
Then implement the zend_module_entry structure in your "mymodule. c:
Zend_module_entry mymodule_module_entry = {
# If zend_module_api_no> = 20010901
Standard_module_header,
# Endif
"Mymodule ",
Mymodule_functions,
Php_minit (mymodule ),
Php_mshutdown (mymodule ),
Php_rinit (mymodule ),
Php_rshutdown (mymodule ),
Null,
# If zend_module_api_no> = 20010901
"0.1 ",
# Endif
Standard_module_properties
};
// Implement php_minit_function () and so on...
Php_minit_function (mymodule)
{
// Your implementation code...
Return success;
}
In fact, the ext_skel program under the ext directory automatically implements these structures when establishing the Code framework of the extension module. Just fill in the required code according to the instructions.