The content is php-5.6.14 for example.
I. Function structure
The kernel defines a PHP function using the Php_function macro wrapper, the extension is no exception, the macro is defined in the No. 343 row of main/php.h;
There are a series of Zend macro wrappers, similar to those named PHP, that are:
/*php-named Zend Macro Wrappers*//*php-named Zend Macro wrapper*/#definePHP_FN ZEND_FN#definePhp_mn zend_mn#definePhp_named_function zend_named_function#definePhp_function zend_function/* php_function is zend_function */#definePhp_method Zend_method#definePhp_raw_named_fe Zend_raw_named_fe#definePhp_named_fe Zend_named_fe#definePhp_fe Zend_fe#definePhp_dep_fe Zend_dep_fe#definePhp_falias Zend_falias#definePhp_dep_falias Zend_dep_falias#definePhp_me Zend_me#definePhp_malias Zend_malias#definePhp_abstract_me Zend_abstract_me#definePhp_me_mapping zend_me_mapping#definePhp_fe_end Zend_fe_end#definePhp_module_startup_n Zend_module_startup_n#definePhp_module_shutdown_n Zend_module_shutdown_n#definePhp_module_activate_n Zend_module_activate_n#definePhp_module_deactivate_n Zend_module_deactivate_n#definePhp_module_info_n Zend_module_info_n#definePhp_module_startup_d Zend_module_startup_d#definePhp_module_shutdown_d Zend_module_shutdown_d#definePhp_module_activate_d zend_module_activate_d#definePhp_module_deactivate_d zend_module_deactivate_d#definePhp_module_info_d Zend_module_info_d/*Compatibility Macros*//*Compatibility Macros*/ #definePhp_minit Zend_module_startup_n#definePhp_mshutdown Zend_module_shutdown_n#definePhp_rinit Zend_module_activate_n#definePhp_rshutdown Zend_module_deactivate_n#definePhp_minfo Zend_module_info_n#definePhp_ginit Zend_ginit#definePhp_gshutdown Zend_gshutdown#definePhp_minit_function zend_module_startup_d/* can be used to define the initial operation of the module */#definePhp_mshutdown_function Zend_module_shutdown_d/* can be used to define what to do when a module is unloaded */#definePhp_rinit_function zend_module_activate_d/* can be used to define what to do when a request is initialized */#definePhp_rshutdown_function zend_module_deactivate_d/* can be used to define what to do at the end of a request */#definePhp_minfo_function zend_module_info_d/* is used to define the module information, such as */in Phpinfo#definePhp_ginit_function zend_ginit_function#definePhp_gshutdown_function zend_gshutdown_function#definePhp_module_globals zend_module_globals
Zend_function on the 68th line of Zend/zend_api.h, they are:
#define ZEND_FN (name) zif_# #name#define zend_mn (name) zim_# #name#define zend_named_function (name) void name (internal_function_parameters)#define zend_function (name) zend_named_function (ZEND_FN (name ))#define Zend_method (classname, name) zend_named_function (Zend_mn (classname# #_ # #name))
The function parameters are internal_function_parameters on line No. 290 of Zend/zend.h, which are:
#define internal_function_parameters int HT, zval *return_value, Zval **return_value_ptr, zval *this_ptr, int return_value_used T SRMLS_DC#define internal_function_param_passthru ht, Return_value, Return_value_ptr, This_ptr, Return_value _used TSRMLS_CC
That is, using Php_function (ABC) to define an ABC function, the preprocessing result is zif_abc (internal_function_parameters), and the following is an experiment:
/*1.c*/#include<stdio.h>#defineZEND_FN (name) zif_# #name#defineZEND_MN (name) zim_# #name#defineZend_named_function (name) void name (Internal_function_parameters)#defineZend_function (name) zend_named_function (ZEND_FN (name))#defineZend_method (classname, name) zend_named_function (Zend_mn (classname# #_ # #name))#defineinternal_function_parameters int HT, zval *return_value, Zval **return_value_ptr, zval *this_ptr, int return_value_used T Srmls_dcintMain () {zend_function (ABC); return 0;}
Using ' Gcc-e-o 1.i 1.c ' to generate preprocessing files 1.i, ' tail 1.i ' to see the final result of the file, a function in the kernel in the form of the following:
int Main () { void zif_abc (intint return_value_used tsrmls_dc); return 0 ;}
The above zif_abc function parameter also has a look strange things tsrmls_dc, thread-safe resource management macros;
In line 166th of tsrm/tsrm.h, they are:
#ifdef ZTS .....#defineTsrmls_fetch () void ***tsrm_ls = (void * * *) ts_resource_ex (0, NULL)#defineTsrmls_fetch_from_ctx (ctx) void ***tsrm_ls = (void * * *) CTX#defineTsrmls_set_ctx (CTX) CTX = (void * * *) Tsrm_ls#defineTSRMG (ID, type, Element) (((Type) (* ((void * *) Tsrm_ls)) [tsrm_unshuffle_rsrc_id (ID)])->element)#definetsrmls_d void ***tsrm_ls#defineTSRMLS_DC, Tsrmls_d#defineTsrmls_c Tsrm_ls#defineTSRMLS_CC, Tsrmls_c#else/* Non ZTS */#defineTsrmls_fetch ()#defineTsrmls_fetch_from_ctx (CTX)#defineTsrmls_set_ctx (CTX)#defineTsrmls_d void#defineTsrmls_dc#defineTsrmls_c#defineTsrmls_cc#endif/* ZTS */
TSRMLS_DC is , Tsrmls_d , that is , void ***tsrm_ls ;
TSRMLS_CC is , Tsrmls_c , that is , Tsrm_ls ;
here is an article about TSRM: secret TSRM (introspecting tsrm)
Two. Parameters
int HT
Zval *return_value, the function internally modifies the pointer, the function executes, and the kernel returns the zval that the pointer points to to the user-side function caller.
Zval **return_value_ptr,
Zval *this_ptr, if this function is a method of a class, is equivalent to $this
int return_value_used, the client calls this function is there is no use of the function return value, used to be 1
Three. Macro functions in Zend_api.h
We traced the two macro functions defined in the file Array_init (), Php_error_docref ().
Array_init () in zend_api.h line No. 363:
#define array_init (ARG) _array_init (ARG), 0 zend_file_line_cc)#define array_init_size (ARG, Size) _array_init (ARG), (size) zend_file_line_cc)#define object_init (ARG) _object_init ((ARG) zend_ FILE_LINE_CC tsrmls_cc)#define object_init_ex (ARG, CE) _object_init_ex ((ARG), (CE) zend_file_line_cc Tsrmls_ CC)#define object_and_properties_init (ARG, CE, properties) _object_and_properties_init ((ARG), ( CE), ( Properties) zend_file_line_cc tsrmls_cc)intuint size ZEND_FILE_LINE_DC);
Implementation of _array_init () on line 1009th of ZEND_API.C:
/* Argument parsing API--Andrei Span style= "color: #008000;" >*/ zend_api int _array_init ( Zval *arg, uint size zend_file_line_dc) /* */ {Alloc_hashtable_rel (z_arrval_p (ARG)); _zend_hash_init (Z_arrval_p (ARG), size, Zval_ptr_dtor, 0 ZEND_FILE_LINE_RELAY_CC); Z_type_p (ARG) = Is_array; return SUCCESS;} /* */
The presence of these API functions makes it easier for us to accomplish a function in the kernel.
Zend.h, zend_file_line_dc on line No. 217:
#ifZend_debug#defineZend_file_line_d const char *__zend_filename, const UINT __zend_lineno#defineZEND_FILE_LINE_DC, Zend_file_line_d#defineZend_file_line_orig_d const char *__zend_orig_filename, const UINT __zend_orig_lineno#defineZEND_FILE_LINE_ORIG_DC, Zend_file_line_orig_d#defineZend_file_line_relay_c __zend_filename, __zend_lineno#defineZEND_FILE_LINE_RELAY_CC, Zend_file_line_relay_c#defineZend_file_line_c __file__, __line__#defineZEND_FILE_LINE_CC, Zend_file_line_c#defineZend_file_line_empty_c NULL, 0#defineZEND_FILE_LINE_EMPTY_CC, Zend_file_line_empty_c#defineZend_file_line_orig_relay_c __zend_orig_filename, __zend_orig_lineno#defineZEND_FILE_LINE_ORIG_RELAY_CC, Zend_file_line_orig_relay_c#defineZend_assert (c) ASSERT (c)#else#defineZend_file_line_d#defineZend_file_line_dc#defineZend_file_line_orig_d#defineZend_file_line_orig_dc#defineZend_file_line_relay_c#defineZend_file_line_relay_cc#defineZend_file_line_c#defineZend_file_line_cc#defineZend_file_line_empty_c#defineZend_file_line_empty_cc#defineZend_file_line_orig_relay_c#defineZend_file_line_orig_relay_cc#defineZend_assert (c)#endif/* Zend_debug */
The above __file_name is the function of a formal parameter name, no special meaning, with two underscores have a very local (private) feeling.
Php_error_docref () in Main/php.h line No. 322:
Begin_extern_c () .../*phpapi void php_error (int type, const char *format, ...);*/PhpapivoidPHP_ERROR_DOCREF0 (Const Char*docref TSRMLS_DC,intTypeConst Char*format, ...) Php_attribute_format (printf, Php_attr_fmt_offset+3, Php_attr_fmt_offset +4); PhpapivoidPHP_ERROR_DOCREF1 (Const Char*docref TSRMLS_DC,Const Char*PARAM1,intTypeConst Char*format, ...) Php_attribute_format (printf, Php_attr_fmt_offset+4, Php_attr_fmt_offset +5); PhpapivoidPhp_error_docref2 (Const Char*docref TSRMLS_DC,Const Char*PARAM1,Const Char*PARAM2,intTypeConst Char*format, ...) Php_attribute_format (printf, Php_attr_fmt_offset+5, Php_attr_fmt_offset +6); #ifdef PHP_WIN32PHPAPIvoidPhp_win32_docref2_from_error (DWORD error,Const Char*PARAM1,Const Char*param2 tsrmls_dc);#endifEnd_extern_c ()#definePhp_error_docref PHP_ERROR_DOCREF0
Example: Two-step write a color extension of the Welcome function
/*{{{ {} custom Welcome*/php_function (Welcome) {php_printf ("It Works, welcome!\n");}/* }}} *//*{{{color_functions[] * * Every user visible function must has a entry in color_functions[]. The available functions are added to the inside.*/ConstZend_function_entry color_functions[] ={Php_fe (confirm_color_compiled, NULL)/*for testing, remove later.*/Php_fe (Welcome, NULL) Php_fe_end/*Must be the last line in color_functions[]*/}; /* }}} */
Make && sudo make install
Run ' php5.6.14-r ' welcome (); ' ' Will output: it works, welcome!
Link:http://www.cnblogs.com/farwish/p/5248686.html
@ Black eyed poet <www.farwish.com>
[PHP-SRC] Understanding functions in the PHP kernel