Learning the PHP kernel-creating PHP extensions and php kernels-extensions
I started to look at the PHP kernel for a while. Now I want to learn and summarize it. Today I will summarize how to create my own PHP extension.
My environment is as follows:
System: Ubuntu 14.04
Php version: 5.5.19
Reference excerpt: use C/C ++ to expand your PHP
One of the main reasons for PHP's success is that it has a large number of available extensions. No matter what the requirements are, web developers are most likely to find such requirements in the PHP release package. The PHP release package includes many extensions that support various databases, graphic file formats, compression, and XML technology extensions.
The introduction of extended APIs has made great progress in PHP3. The extended API mechanism makes it easy for the PHP development community to develop dozens of extensions. Now, the two versions have passed, and the API is still very similar to PHP3. The main idea of extension is to hide the internal mechanism and Script Engine of PHP from the extension writer as much as possible. Developers only need to familiarize themselves with the API.
There are two reasons to write your own PHP extensions. The first reason is that PHP needs to support a technology that she does not yet support. This usually includes some ready-made C function libraries to provide PHP interfaces. For example, if a database named FooBase has been released to the market, you need to create a PHP extension to help you call the C function library of FooBase from PHP. This job may be done by only one person and shared by the entire PHP community (if you want ). The second reason is not very general: You need to write some business logic for performance or functional reasons.
Suppose you are developing a website, and you need a function that repeats strings n times. The following is an example written in PHP:
function util_str_repeat($string, $n){ $result = ""; for($i = 0; $i < $n; $i++){ $result .= $string; } return $result;} util_str_repeat("One", 3);// returns "OneOneOne".util_str_repeat("One", 1);// returns "One".
For some strange reasons, you need to call this function from time to time and pass it to a long string and a large value of n. This means that there is a considerable amount of string connections and memory reallocation in the script, which significantly reduces the script execution speed. If a function can allocate a large amount of memory to store the result string more quickly and repeat $ string n times, you do not need to allocate memory in each loop iteration.
The first step to create a function for expansion is to write a function definition file that defines the original form of the function provided by the extension. In this example, the defined function has only one row of util_str_repeat ():
string util_str_repeat(string str, int n)
The general format of the function definition file is a function line. You can define optional parameters and use a large number of PHP types, including bool, float, int, and array.
Save it as the util. def file to the directory tree of the PHP original code (that is, put it in the same directory as the ext_skel file, and my directory is/usr/share/php5 /).
Then it is time to run the function definition file through the skeleton constructor. The constructor script is ext_skel. Suppose you save the function definition in a file named util. def, and you want to name the extension util. Run the following command to create the extension SKELETON:
sudo ./ext_skel --extname=util --proto=util.def
After execution, I reported the following error:
./ext_skel: 1: cd: can't cd to /usr/lib/php5/skeletonCreating directory utilawk: cannot open /create_stubs (No such file or directory)Creating basic files: config.m4 config.w32 .svnignore util.c./ext_skel: 216: ./ext_skel: cannot open /skeleton.c: No such file php_util.h./ext_skel: 234: ./ext_skel: cannot open /php_skeleton.h: No such file CREDITS./ext_skel: 238: ./ext_skel: cannot open /CREDITS: No such file EXPERIMENTAL./ext_skel: 242: ./ext_skel: cannot open /EXPERIMENTAL: No such file tests/001.phpt./ext_skel: 247: ./ext_skel: cannot open /tests/001.phpt: No such file util.php./ext_skel: 251: ./ext_skel: cannot open /skeleton.php: No such filerm: cannot remove ‘function_entries’: No such file or directoryrm: cannot remove ‘function_declarations’: No such file or directoryrm: cannot remove ‘function_stubs’: No such file or directory [done].To use your new extension, you will have to execute the following steps:1. $ cd ..2. $ vi ext/util/config.m43. $ ./buildconf4. $ ./configure --[with|enable]-util5. $ make6. $ ./php -f ext/util/util.php7. $ vi ext/util/util.c8. $ makeRepeat steps 3-6 until you are satisfied with ext/util/config.m4 andstep 6 confirms that your module is compiled into PHP. Then, start writingcode and repeat the last two steps as often as necessary.
Obviously, the/usr/lib/php5/skeleton path is incorrect. Edit the ext_skel file and change/usr/lib/php5/skeleton to/usr/share/php5/skeleton, remove the generated util folder and execute the previous command again. The prompt is as follows:
Creating directory utilCreating basic files: config.m4 config.w32 .svnignore util.c php_util.h CREDITS EXPERIMENTAL tests/001.phpt util.php [done].To use your new extension, you will have to execute the following steps:1. $ cd ..2. $ vi ext/util/config.m43. $ ./buildconf4. $ ./configure --[with|enable]-util5. $ make6. $ ./php -f ext/util/util.php7. $ vi ext/util/util.c8. $ makeRepeat steps 3-6 until you are satisfied with ext/util/config.m4 andstep 6 confirms that your module is compiled into PHP. Then, start writingcode and repeat the last two steps as often as necessary.
Then, compile the extension using static compilation. To enable compilation of extensions, You need to modify the config. m4 file under the extension directory util. Expansion does not wrap any external C library, you need to add the support-enable-util configuration switch to the PHP compilation system (the-with-extension switch is used for extensions that require users to specify the relevant C library path ). Find the following content:
dnl PHP_ARG_ENABLE(util, whether to enable util support,dnl Make sure that the comment is aligned:dnl [ --enable-util Enable util support])
Remove the previous dnl and modify it to the following result:
PHP_ARG_ENABLE(util, whether to enable util support,Make sure that the comment is aligned:[ --enable-util Enable util support])
Modify the util. c file and find the following code:
PHP_FUNCTION(util_str_repeat){ char *str = NULL; int argc = ZEND_NUM_ARGS(); int str_len; long n; if (zend_parse_parameters(argc TSRMLS_CC, "sl", &str, &str_len, &n) == FAILURE) return; php_error(E_WARNING, "util_str_repeat: not yet implemented");}
Modify it to the following code:
PHP_FUNCTION(util_str_repeat){ char *str = NULL; int argc = ZEND_NUM_ARGS(); int str_len; long n; char *result; /* Points to resulting string */ char *ptr; /* Points at the next location we want to copy to */ int result_length; /* Length of resulting string */ if (zend_parse_parameters(argc TSRMLS_CC, "sl", &str, &str_len, &n) == FAILURE) return; /* Calculate length of result */ result_length = (str_len * n); /* Allocate memory for result */ result = (char *) emalloc(result_length + 1); /* Point at the beginning of the result */ ptr = result; while (n--) { /* Copy str to the result */ memcpy(ptr, str, str_len); /* Increment ptr to point at the next position we want to write to */ ptr += str_len; }
/* Null terminate the result. Always null-terminate your strings even if they are binary strings */ *ptr = '\0'; /* Return result to the scripting engine without duplicating it*/ RETURN_STRINGL(result, result_length, 0);}
The specific content will not be mentioned here, and will be written later.
Then compile and install the SDK. In the util directory, run the following command (sudo may be required for all commands ):
phpize./configuremakemake testmake install
Then configure the generated extension file. In php5.5, go to the/etc/php5/mod-available Directory, create the util. ini file, and write the following content:
extension=util.so
Then enable util Extension
sudo php5enmod util
Finally, restart php-fpm.
sudo service php5-fpm restart
Create a PHP file and test it. The test file is as follows:
<?phpfor ($i = 1; $i <= 3; $i++) { print util_str_repeat("CraryPrimitiveMan ", $i); print "\n";}?>
The execution result is as follows:
CraryPrimitiveMan CraryPrimitiveMan CraryPrimitiveMan CraryPrimitiveMan CraryPrimitiveMan CraryPrimitiveMan
In this way, we have successfully created an extension that contains simple PHP functions.
Image stealing ~~
Come here today ~~