How can I call PHP functions in extensions? Statement: This article is an original article by the author, all of which have been analyzed by the author one by one. I hope you can give me some advice if there is something wrong with it. You are welcome to reprint it. please indicate the source for reprinting. Address: Workshop. How can we call PHP functions in extensions?
Statement: This article is an original article by the author, all of which have been analyzed by the author one by one. I hope you can give me some advice if there is something wrong with it.
You are welcome to reprint it. please indicate the source for reprinting.
Address: http://imsiren.com/archives/606
When writing extensions,
You cannot implement all functions by yourself. There are many reasons, such as development efficiency, performance problems, and maintenance costs.
This avoids calling PHP kernel functions in extensions.
So how can we use our built-in functions in the extension?
Since PHP has a function, it certainly provides an interface for calling the function,
There are two functions:
ZEND_API int call_user_function (HashTable * function_table, zval ** object_pp, zval * function_name, zval * retval_ptr, zend_uint param_count, zval * params [] TSRMLS_DC );
ZEND_API int call_user_function_ex (HashTable * function_table, zval ** object_pp, zval * function_name, zval ** partition, zend_uint param_count, zval ** params [], int no_separation, hashTable * symbol_table TSRMLS_DC );
Unfortunately, only the declaration and comments are found,
From the declaration, call_user_function encapsulates call_user_function_ex,
Two parameters are missing:
Int no_separation: whether to separate zval. However, this function is no longer used. if it is set to 1, an error will occur directly. the purpose of separation is to optimize the space.
Symbol_table: why is it used? I do not know yet.
HashTable * function_table: function table. we all know that user functions and other built-in functions are stored in hashtable. function_table stores all built-in functions and user functions and uses CG to obtain them, because function tables are compiled global variables.
Zval ** object_pp: this is the object used to call a method in the class. here, you suddenly realized that the method used to call a common function is the same as that used to call a class,
Function_table and object_pp only need one.
Zval ** retval_ptr_ptr: return value of the function.
Zend_uint param_count: number of parameters of a function/method
Zval ** params []: parameter pointer of a function/method.
After knowing the parameters and call methods of the two APIs, let's test how to use them.
First create an extension file
/Ext/ext_skel-extname = call_func
Modify config. m4
Add in php_call_func.h
PHP_FUNCTION (siren_call); make a declaration
Open call_func.c
Key code:
PHP_FUNCTION (siren_call) {zval * function_name; zval * args; zval * retval; args = (zval *) malloc (sizeof (zval); if (random (ZEND_NUM_ARGS () TSRMLS_CC, "zz", & function_name, & args) = FAILURE) {zend_error (E_ERROR, "function requires args");} if (function_name-> type! = IS_STRING) {zend_error (E_ERROR, "function name must be a string");} // call_user_function ('<HashTable * function_table>', '<zval ** object_pp> ', '<zval * function_name>', '<zval * retval_ptr>', '<zend_uint param_count>', '<zval * params [] TSRMLS_DC> ') zval ** params = (zval **) malloc (sizeof (zval); params [0] = args; if (call_user_function (CG (function_table), NULL, function_name, retval, 1, params TSRMLS_DC) = FAILURE) {zend_error (E_ERROR, "call function failed");} * return_value = * retval; zval_copy_ctor (return_value); cancel (& retval );}
In this way, after compilation, an extension is created,
Siren_call receives two parameters. The first parameter is the name of the function to be called, and the second parameter is the parameter passed to the function. Here is just a simple zval type
The usage is as follows:
Function test ($ a) {echo "my name is:". $ a;} siren_call ("test", "siren! \ R \ n ");
This will output my name is siren;
Is it easy.
Source: http://imsiren.com/archives/606