# php 扩展开发 **Repository Path**: dddxiu/phpextended_development ## Basic Information - **Project Name**: php 扩展开发 - **Description**: No description available - **Primary Language**: C - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-04-30 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # php 扩展开发 ### PHP 的函数注册 ``` # 声明参数.也可写在函数体中 ZEND_BEGIN_ARG_INFO_EX(arginfo_celsius_to_fahrenheit, 0, 0, 1) ZEND_ARG_INFO(0, celsius) ZEND_END_ARG_INFO(); static double php_celsius_to_fahrenheit(double c) { return (((double)9/5) * c) + 32 ; } # 声明函数 PHP_FUNCTION(celsius_to_fahrenheit) { double c; if (zend_parse_parameters(ZEND_NUM_ARGS(), "d", &c) == FAILURE) { return; } RETURN_DOUBLE(php_celsius_to_fahrenheit(c)); } # 注册模块函数 static const zend_function_entry pib_functions[] = { PHP_FE(fahrenheit_to_celsius, arginfo_fahrenheit_to_celsius) PHP_FE(celsius_to_fahrenheit, arginfo_celsius_to_fahrenheit) PHP_FE_END }; ``` | 参数宏 | 含义 | |---|---| |Z_PARAM_ARRAY() | /* old "a" */ | |Z_PARAM_ARRAY_OR_OBJECT() | /* old "A" */ | |Z_PARAM_BOOL() | /* old "b" */ | |Z_PARAM_CLASS() | /* old "C" */ | |Z_PARAM_DOUBLE() | /* old "d" */ | |Z_PARAM_FUNC() | /* old "f" */ | |Z_PARAM_ARRAY_HT() | /* old "h" */ | |Z_PARAM_ARRAY_OR_OBJECT_HT() | /* old "H" */ | |Z_PARAM_LONG() | /* old "l" */ | |Z_PARAM_STRICT_LONG() | /* old "L" */ | |Z_PARAM_OBJECT() | /* old "o" */ | |Z_PARAM_OBJECT_OF_CLASS() | /* old "O" */ | |Z_PARAM_PATH() | /* old "p" */ | |Z_PARAM_PATH_STR() | /* old "P" */ | |Z_PARAM_RESOURCE() | /* old "r" */ | |Z_PARAM_STRING() | /* old "s" */ | |Z_PARAM_STR() | /* old "S" */ | |Z_PARAM_ZVAL() | /* old "z" */ | |Z_PARAM_VARIADIC() | /* old "+" and "*" */ | [php_functions](http://www.phpinternalsbook.com/php7/extensions_design/php_functions.html) [参数声明](http://www.phpinternalsbook.com/php7/extensions_design/php_functions.html#declaring-function-arguments) ### 模块的常量定义 ``` #define TEMP_CONVERTER_TO_FAHRENHEIT 2 #define TEMP_CONVERTER_TO_CELSIUS 1 PHP_MINIT_FUNCTION(pib) { REGISTER_LONG_CONSTANT("TEMP_CONVERTER_TO_CELSIUS", TEMP_CONVERTER_TO_CELSIUS, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TEMP_CONVERTER_TO_FAHRENHEIT", TEMP_CONVERTER_TO_FAHRENHEIT, CONST_CS|CONST_PERSISTENT); return SUCCESS; } ``` ### PHP_ARRAY 处理 ``` ZEND_BEGIN_ARG_INFO_EX(arginfo_multiple_fahrenheit_to_celsius, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, temperatures, 0) ZEND_END_ARG_INFO(); static const zend_function_entry pib_functions[] = { /* ... */ PHP_FE(multiple_fahrenheit_to_celsius, arginfo_multiple_fahrenheit_to_celsius) PHP_FE_END }; PHP_FUNCTION(multiple_fahrenheit_to_celsius) { HashTable *temperatures; zval *data; if (zend_parse_parameters(ZEND_NUM_ARGS(), "h", &temperatures) == FAILURE) { return; } if (zend_hash_num_elements(temperatures) == 0) { return; } array_init_size(return_value, zend_hash_num_elements(temperatures)); ZEND_HASH_FOREACH_VAL(temperatures, data) zval dup; ZVAL_COPY_VALUE(&dup, data); convert_to_double(&dup); add_next_index_double(return_value, php_fahrenheit_to_celsius(Z_DVAL(dup))); ZEND_HASH_FOREACH_END(); } ``` ### PHP的引用传参 ``` ZEND_BEGIN_ARG_INFO_EX(arginfo_fahrenheit_to_celsius, 0, 0, 1) ZEND_ARG_INFO(1, fahrenheit) # 1:引用传参,0:非引用传参 ZEND_END_ARG_INFO(); PHP_FUNCTION(fahrenheit_to_celsius) { double result; zval *param; # 引用传参需要通过zval来接收,且参数字符为"z" if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", ¶m) == FAILURE) { return; } ZVAL_DEREF(param); convert_to_double(param); ZVAL_DOUBLE(param, php_fahrenheit_to_celsius(Z_DVAL_P(param))); } ``` ### 管理全局资源 TSRM (Thread Safe Resource Manager) ``` ZEND_BEGIN_MODULE_GLOBALS(pib) zend_long rnd; zend_ulong cur_score; zval scores; ZEND_END_MODULE_GLOBALS(pib) ZEND_DECLARE_MODULE_GLOBALS(pib) static void pib_rnd_init(void) { /* reset current score as well */ PIB_G(cur_score) = 0; php_random_int(0, 100, &PIB_G(rnd), 0); } PHP_GINIT_FUNCTION(pib) { /* ZEND_SECURE_ZERO is a memset(0). Could resolve to bzero() as well */ ZEND_SECURE_ZERO(pib_globals, sizeof(*pib_globals)); } ZEND_BEGIN_ARG_INFO_EX(arginfo_guess, 0, 0, 1) ZEND_ARG_INFO(0, num) ZEND_END_ARG_INFO() PHP_RINIT_FUNCTION(pib) { array_init(&PIB_G(scores)); pib_rnd_init(); return SUCCESS; } PHP_RSHUTDOWN_FUNCTION(pib) { zval_dtor(&PIB_G(scores)); return SUCCESS; } PHP_FUNCTION(pib_guess) { zend_long r; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &r) == FAILURE) { return; } if (r == PIB_G(rnd)) { add_next_index_long(&PIB_G(scores), PIB_G(cur_score)); pib_rnd_init(); RETURN_TRUE; } PIB_G(cur_score)++; if (r < PIB_G(rnd)) { RETURN_STRING("more"); } RETURN_STRING("less"); } PHP_FUNCTION(pib_get_scores) { if (zend_parse_parameters_none() == FAILURE) { return; } RETVAL_ZVAL(&PIB_G(scores), 1, 0); } PHP_FUNCTION(pib_reset) { if (zend_parse_parameters_none() == FAILURE) { return; } pib_rnd_init(); } static const zend_function_entry func[] = { PHP_FE(pib_reset, NULL) PHP_FE(pib_get_scores, NULL) PHP_FE(pib_guess, arginfo_guess) PHP_FE_END }; zend_module_entry pib_module_entry = { STANDARD_MODULE_HEADER, "pib", func, /* Function entries */ NULL, /* Module init */ NULL, /* Module shutdown */ PHP_RINIT(pib), /* Request init */ PHP_RSHUTDOWN(pib), /* Request shutdown */ NULL, /* Module information */ "0.1", /* Replace with version number for your extension */ PHP_MODULE_GLOBALS(pib), PHP_GINIT(pib), NULL, NULL, STANDARD_MODULE_PROPERTIES_EX }; ``` ### phpinfo ``` #include "php/main/SAPI.h" #include "ext/standard/info.h" #define PIB_TXT "PHPInternalsBook Authors" #define PIB_HTML "