Why use C to extend
C is statically compiled and executes much more efficiently than the PHP code. The same arithmetic code, using C to develop, performance will be hundreds of times times higher than PHP.
In addition, the C extension is loaded at the start of the process, and the PHP code can only manipulate the request lifecycle data, and the C extension can operate more broadly.
Creating an extended skeleton
##本例用的php版本的是5.3.3cd php-5.3.3/ext/./ext_skel --extname=myfun --proto=myfun.def##执行成功后会生成myfun的编译文件ls myfun/config.m4 config.w32 CREDITS .cvsignore EXPERIMENTAL myfun.c myfun.php php_myfun.h tests
Modify CONFIG.M4
Config.m4 the meaning of dnl in the notes
##动态编译选项,通过.so的方式链接,去掉dnl注释PHP_ARG_WITH(myfun, for myfun support,[ --with-myfun Include myfun support])##静态编译选项,通过enable来启用,去掉dnl注释PHP_ARG_ENABLE(myfun, whether to enable myfun support,[ --enable-myfun Enable myfun support])
Modify complete under compilation
phpize./configure --enable-myfunmakemake install
In Myfun there is a PHP test script that performs the test
php -d enable_dl=On myfile.php
Output Result:
Functions available in the test extension:confirm_myfun_compiledCongratulations! You have successfully modified ext/myfun/config.m4. Module myfun is now compiled into PHP.
Actually, confirm_myfun_compiled is the test function that the build tool helps us build.
Create a HelloWorld function
Now let's create our own function helloWorld()
, the function is outputHello World!
vim myfun/php_myfun.h##在PHP_FUNCTION(confirm_myfun_compiled); 下追加一行PHP_FUNCTION(helloWorld);
Implementing HelloWorld Entities
vim myfun/myfun.c##zend_function_entry myfun_functions 补充要实现的函数const zend_function_entry myfun_functions[] = { PHP_FE(confirm_myfun_compiled, NULL) /* For testing, remove later. */ PHP_FE(helloWorld, NULL) /*这是补充的一行,末尾没有逗号*/ {NULL, NULL, NULL} /* Must be the last line in myfun_functions[] */};##在末尾实现helloworld的内容PHP_FUNCTION(helloWorld){ php_printf("Hello World!\n"); RETURN_TRUE;}
Re-compiling
./configure && make && make install
Test
php -d enable_dl=On -r "dl(‘myfun.so‘);helloWorld();"Hello World!php -d enable_dl=On -r "dl(‘myfun.so‘);print confirm_myfun_compiled(‘helloWorld‘);"Congratulations! You have successfully modified ext/myfun/config.m4. Module helloWorld is now compiled into PHP.
Header file Analysis
#ifndef php_myfun_h#define php_myfun_hextern zend_module_entry myfun_module_entry; #define PHPEXT_MYFUN_PTR & Myfun_module_entry#ifdef php_win32# define PHP_MYFUN_API __declspec (dllexport) #elif defined (__gnuc__) && __g nuc__ >= 4# define PHP_MYFUN_API __attribute__ ((Visibility ("default")) #else # define Php_myfun_api#endif#i Fdef zts#include "TSRM.h" #endifPHP_MINIT_FUNCTION (myfun); /* When PHP is loaded, the module startup function is called by the engine. This allows the engine to do some initialization such as resource types, registering INI variables, and so on. */php_mshutdown_function (Myfun); /* When PHP is completely closed, the module shutdown function is called by the engine. Typically used to unregister INI entries */php_rinit_function (myfun); /* At the beginning of each PHP request, the start function is called before the request. Typically used to manage pre-request logic. */php_rshutdown_function (Myfun); /* At the end of each PHP request, the close function is called before the request. The logic of starting a function is often applied before a cleanup request. */php_minfo_function (Myfun); /* When calling Phpinfo (), the module information function is called to print out the module information. */php_function (confirm_myfun_compiled); /* For testing, remove later. */php_function (HelloWorld), #ifdef zts#define myfun_g (v) tsrmg (myfun_globals_id, zend_myfun_globals *, v) #else # define Myfun_g (v) (MYFUN_GLOBALS.V) #endif #endif/* Php_myfun_h */
confirm_myfun_compiled Analysis
Php_function (confirm_myfun_compiled)//using Macro php_function (), the macro can generate a function prototype suitable for the Zend engine {char *arg = NULL; int Arg_len, Len; Char *STRG; The parameter that gets passed by the function//The first argument is the number of arguments passed to the function. The usual practice is to pass it Zend_num_args (). This is a macro that represents the total number of arguments passed to the function. The second parameter is for thread safety and always passes the TSRMLS_CC macro. The third argument is a string that specifies the type of argument the function expects, followed by a list of variables that need to be updated with the parameter value. Because PHP uses loose variable definitions and dynamic type judgments, doing so makes it possible to convert different types of parameters into desired types. For example, if a user passes an integer variable and the function needs a floating-point number, then Zend_parse_parameters () automatically converts the integer to the corresponding floating-point number. If the actual value cannot be converted to the desired type (such as shaping into an array shape), a warning is triggered. /* Type indicator l long symbol integer d double floating-point number s char *, int binary string, length b ze Nd_bool logic type (1 or 0) r zval * Resource (file pointer, database connection, etc.) a zval * Union array o Zval * Any type of object O Zval * Specifies the type of object. The class type required to provide the target object Z zval * No action Zval *///Fourth parameter for passed parameter data reference//fifth parameter is the number of arguments passed if (Zend _parse_parameters (Zend_num_args () tsrmls_cc, "s", &arg, &arg_len) = = FAILURE) {//Get parameters passed by function Return } len = spprintf (&STRG, 0, "congratulations! You have successfully modified EXT/%.78S/CONFIG.M4. Module%.78s is now compiled into PHP. "," Myfun ", Arg); /* The control is returned to PHP by setting Return_type (). The following table explains most of the macros that exist. Retval_long (L) integer Retval_bool (b) Boolean (1 or 0) retval_null () NULL retval_double (d) floating-point number Retval_string (S, DUP) string. If the DUP is 1, the engine calls Estrdup () to repeat S, using the copy. If the DUP is 0, use a string value of s Retval_stringl (S, l, DUP) length L. As with the previous macro, but because the length of s is specified, it is faster. Retval_true returns a Boolean value of TRUE. Notice that the macro has no parentheses. Retval_false returns a Boolean value of FALSE. Notice that the macro has no parentheses. Retval_resource (r) resource handle. */Return_stringl (STRG, Len, 0);}
From for notes (Wiz)
PHP extension Development--01. Writing a HelloWorld extension