Learning of PHP kernel--Creating PHP extensions
One of the main reasons for PHP's success is the large number of extensions available. No matter what needs web developers have, they are most likely to be found in PHP distribution packages. The PHP distribution package includes many extensions that support various databases, graphics file formats, compression, and XML technology extensions.
The introduction of extension API has made great progress in PHP3. The extension API mechanism allows the PHP development community to easily develop dozens of extensions. Now, two versions later, the API is still very similar to PHP3. The main idea of extensions is to hide the internal mechanisms of PHP and the scripting engine itself from extension writers as much as possible, and only require developers to be familiar with the API.
There are two reasons to write your own PHP extension. The first reason is: PHP needs to support a technology that it does not yet support. This usually involves wrapping some off-the-shelf C library to provide a PHP interface. For example, if a database called FooBase is launched on the market, you need to create a PHP extension to help you call FooBase's C function library from PHP. This work might be done by just one person and then shared by the entire PHP community (if you will). The second, less common reason is that you need to write some business logic for performance or functionality reasons.
Suppose you are developing a website and need a function that repeats a string 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".
Suppose that for some strange reasons, you need to call this function from time to time, and you also need to pass a long string and a large value n to the function. This means that there is a considerable amount of string concatenation and memory reallocation in the script, which can significantly slow down script execution. If there was a function that could faster allocate a large and sufficient memory to store the result string, and then repeat $string n times, there would be no need to allocate memory on each loop iteration.
The first step to create a function for the extension is to write a function definition file, which defines the function prototype provided by the extension. In this example, there is only one line to define the function prototype util_str_repeat():
string util_str_repeat(string str, int n)
The general format of a function definition file is one function per line. You can define optional parameters and use a large number of PHP types, including: bool, float, int, array, etc.
Save it as a util.def file in the PHP original code directory tree (that is, put it in the same directory as the ext_skel file, my directory is /usr/share/php5/).
Then it’s time to run the function definition file by extending the skeleton constructor. The constructor script is ext_skel. Assuming you save your function definitions in a file called util.def, and you want to name your 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/skeleton
Creating directory util
awk: 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 file
rm: cannot remove ‘function_entries’: No such file or directory
rm: cannot remove ‘function_declarations’: No such file or directory
rm: 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.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-util
5. $ make
6. $ ./php -f ext/util/util.php
7. $ vi ext/util/util.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/util/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
Obviously the path to /usr/lib/php5/skeleton is wrong. Edit the ext_skel file, change /usr/lib/php5/skeleton to /usr/share/php5/skeleton, and then remove the generated util file. folder and execute the previous command again. After success, the prompt is as follows:
Creating directory util
Creating 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.m4
3. $ ./buildconf
4. $ ./configure --[with|enable]-util
5. $ make
6. $ ./php -f ext/util/util.php
7. $ vi ext/util/util.c
8. $ make
Repeat steps 3-6 until you are satisfied with ext/util/config.m4 and
step 6 confirms that your module is compiled into PHP. Then, start writing
code and repeat the last two steps as often as necessary.
Then compile the extension using static compilation. In order for the extension to be compiled, the config.m4 file in the extension directory util/ needs to be modified. The extension does not wrap any external C library, you need to add support for the --enable-util configuration switch to the PHP build system (the --with-extension switch is used for extensions that require the user to specify the path to the relevant C library). Found the following:
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])
Then 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 implemented yet");
}
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 = '
/* Return result to the scripting engine without duplicating it*/
RETURN_STRINGL(result, result_length, 0);
}
I won’t talk about the specific content here, I will write about it later.
Then it’s compilation and installation. In the util directory, the command is as follows (sudo may be required for each command):
phpize
./configure
make
make test
make install
Then configure the generated extension file. In the php5.5 version, go to the /etc/php5/mods-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:
for ($i = 1; $i <= 3; $i ) {
print util_str_repeat("CraryPrimitiveMan ", $i);
print "n";
}
?>
The execution results are as follows:
CraryPrimitiveMan
CraryPrimitiveMan CraryPrimitiveMan
CraryPrimitiveMan CraryPrimitiveMan CraryPrimitiveMan
In this way we have successfully created an extension containing a simple PHP function.
http://www.bkjia.com/PHPjc/984112.htmlwww.bkjia.comtruehttp: //www.bkjia.com/PHPjc/984112.htmlTechArticleLearning of PHP Core--Creating PHP Extensions One of the main reasons for PHP's success is that it has a large number of available Extension. No matter what needs web developers have, such needs are most likely to be developed in PHP...
Statement:The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn