PHP扩展开发
一、下载源码包,进入PHP扩展源码目录:php/81/src/ext
二、执行:php ext_skel.php --ext=WxworkFinanceSdk
三、生成arginfo,执行命令:php ../ext_skel.php build/gen_stub.php wxworkfinancesdk.stub.php(其中wxworkfinancesdk.stub.php为php类示例)
四、开发期间可以用 valgrind 作为内存泄漏测试工具:
1、安装:yum install valgrind
2、执行命令:valgrind --tool=memcheck --leak-check=yes php ./test.php(若要输出至文本:valgrind --tool=memcheck --leak-check=yes php ./test.php > valgrind-report.txt 2>&1)
五、下面以企业微信扩展示例代码:
wxwork_finance_sdk.c 文件
/* $Id$ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_wxwork_finance_sdk.h" #include "wxwork_finance_arginfo.h" /* If you declare any globals in php_wxwork_finance_sdk.h uncomment this: ZEND_DECLARE_MODULE_GLOBALS(wxwork_finance_sdk) */ /* True global resources - no need for thread safety here */ static int le_wxwork_finance_sdk; static zend_class_entry *wxwork_finance_sdk_ce; static zend_class_entry *wxwork_finance_sdk_exception_ce; /** * */ static WeWorkFinanceSdk_t* wxwork_finance_internal_get_sdk(zval *wxwork_class_this) { ze_WeWorkFinanceSdk_object *ce = Z_OBJCE_P(wxwork_class_this); zval *wecom_sdk_zval = zend_read_property(ce, Z_OBJ_P(wxwork_class_this), WXWORK_SDK_G_NAME, WXWORK_SDK_G_NAME_SIZE, 0, NULL); WeWorkFinanceSdk_t *wecom_sdk = (WeWorkFinanceSdk_t *)Z_PTR_P(wecom_sdk_zval); return wecom_sdk; } /** options = [ 'proxy_host' => 'http://www.baidu.com', 'proxy_password' => 'helloworld' ] */ PHP_METHOD(WxworkFinanceSdk, __construct) { char *corp_id, *secret; size_t corp_id_len, secret_len; zval *option_zval = NULL; zval wecom_sdk_zval; WeWorkFinanceSdk_t *wecom_sdk; if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|a", &corp_id, &corp_id_len, &secret, &secret_len, &option_zval) == FAILURE) { zend_error(E_ERROR, "param error"); return; } if (corp_id_len == 0 || secret_len == 0) { zend_throw_exception(spl_ce_InvalidArgumentException, "corpId and secret cannot be bull", 0); return; } zval *this = getThis(); ze_WeWorkFinanceSdk_object *ce = Z_OBJCE_P(this); // init wecom finance sdk wecom_sdk = NewSdk(); int ret = Init(wecom_sdk, corp_id, secret); if (ret != 0) { zend_throw_exception(wxwork_finance_sdk_exception_ce, "Call WeWorkFinanceSdk_t Init error", ret); return; } ZVAL_PTR(&wecom_sdk_zval, wecom_sdk); zend_update_property(ce, Z_OBJ_P(ZEND_THIS), WXWORK_SDK_G_NAME, WXWORK_SDK_G_NAME_SIZE, &wecom_sdk_zval); zend_update_property_string(ce, Z_OBJ_P(ZEND_THIS), "_corpId", sizeof("_corpId") - 1, corp_id); zend_update_property_string(ce, Z_OBJ_P(ZEND_THIS), "_secret", sizeof("_secret") - 1, secret); if (option_zval) { zval *proxy_host_zval = zend_hash_find(Z_ARR_P(option_zval), zend_string_init("proxy_host", sizeof("proxy_host") - 1, 0)); if (proxy_host_zval != NULL) { zval *proxy_password_zval = zend_hash_find(Z_ARR_P(option_zval), zend_string_init("proxy_password", sizeof("proxy_password") - 1, 0)); zend_update_property_string(ce, Z_OBJ_P(ZEND_THIS), "_proxy_host", sizeof("_proxy_host") - 1, Z_STRVAL_P(proxy_host_zval)); if (proxy_password_zval != NULL) { zend_update_property_string(ce, Z_OBJ_P(ZEND_THIS), "_proxy_password", sizeof("_proxy_password") - 1, Z_STRVAL_P(proxy_password_zval)); } } zval *timeout_zval = zend_hash_find(Z_ARR_P(option_zval), zend_string_init("timeout", sizeof("timeout") - 1, 0)); if (timeout_zval != NULL) { zend_update_property_long(ce, Z_OBJ_P(ZEND_THIS), "_timeout", sizeof("_timeout") - 1, zval_get_long(timeout_zval)); } } } PHP_METHOD(WxworkFinanceSdk, __destruct) { zval *this = getThis(); WeWorkFinanceSdk_t *wecom_sdk = wxwork_finance_internal_get_sdk(this); DestroySdk(wecom_sdk); TRACE("release wecom_sdk"); } /** {{{ proto public WxworkFinanceSdk::getChatData(int $seq, int $limit) */ PHP_METHOD(WxworkFinanceSdk, getChatData) { zend_long seq, limit = 0; if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &seq, &limit) == FAILURE) { return; } Slice_t *chat_data = NewSlice(); if (NULL == chat_data) { zend_error(E_ERROR, "There is not enough memory!"); return; } zval *this = getThis(); ze_WeWorkFinanceSdk_object *ce = Z_OBJCE_P(this); // zend_class_entry *ce = Z_OBJCE_P(this); WeWorkFinanceSdk_t *wecom_sdk = wxwork_finance_internal_get_sdk(this); zval *proxy_host_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_proxy_host", sizeof("_proxy_host") - 1, 0, NULL); zval *proxy_password_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_proxy_password", sizeof("_proxy_password") - 1, 0, NULL); zval *timeout_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_timeout", sizeof("_timeout") - 1, 0, NULL); int ret = GetChatData(wecom_sdk, (int)seq, (int)limit, Z_STRVAL_P(proxy_host_zval), Z_STRVAL_P(proxy_password_zval), zval_get_long(timeout_zval), chat_data); if (0 != ret) { zend_throw_exception(wxwork_finance_sdk_exception_ce, "Call WeWorkFinanceSdk_t GetChatData error", ret); return; } zend_string *s = zend_string_init(GetContentFromSlice(chat_data), GetSliceLen(chat_data), 0); RETURN_STR(s); zend_string_release(s); zval_ptr_dtor(proxy_host_zval); zval_ptr_dtor(proxy_password_zval); zval_ptr_dtor(timeout_zval); FreeSlice(chat_data); } /* }}} */ /** {{{ proto WxworkFinanceSdk->decryptData(string $encryptRandomKey, string $encryptData) */ PHP_METHOD(WxworkFinanceSdk, decryptData) { zend_string *encrypt_random_key, *encrypt_data; if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &encrypt_random_key, &encrypt_data) == FAILURE) { return; } Slice_t *msg = NewSlice(); int ret = DecryptData(ZSTR_VAL(encrypt_random_key), ZSTR_VAL(encrypt_data), msg); if (ret != 0) { zend_throw_exception(spl_ce_InvalidArgumentException, "DecryptData data error", ret); return; } zend_string *return_msg = zend_string_init(GetContentFromSlice(msg), GetSliceLen(msg), 0); RETURN_STR(return_msg); FreeSlice(msg); zend_string_release(return_msg); } /** {{{ proto WxworkFinanceSdk->downloadMedia(string $filedId, string $saveTo) */ PHP_METHOD(WxworkFinanceSdk, downloadMedia) { zend_string *sdk_filedid, *file_saveto; if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &sdk_filedid, &file_saveto) == FAILURE) { return; } zval *this = getThis(); // zend_class_entry *ce = Z_OBJCE_P(this); ze_WeWorkFinanceSdk_object *ce = Z_OBJCE_P(this); zval *proxy_host_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_proxy_host", sizeof("_proxy_host") - 1, 0, NULL); zval *proxy_password_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_proxy_password", sizeof("_proxy_password") - 1, 0, NULL); zval *timeout_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_timeout", sizeof("_timeout") - 1, 0, NULL); FILE *fp = fopen(ZSTR_VAL(file_saveto), "wb"); if (NULL == fp) { zend_throw_exception(wxwork_finance_sdk_exception_ce, "Open", 0); return; } MediaData_t *media_data = NewMediaData(); if (NULL == media_data) { zend_error(E_ERROR, "There is not enough memory!"); return; } WeWorkFinanceSdk_t *wecom_sdk = wxwork_finance_internal_get_sdk(this); do { int ret = GetMediaData(wecom_sdk, GetOutIndexBuf(media_data), ZSTR_VAL(sdk_filedid), Z_STRVAL_P(proxy_host_zval), Z_STRVAL_P(proxy_password_zval), zval_get_long(timeout_zval), media_data); if (0 != ret) { FreeMediaData(media_data); fclose(fp); zend_throw_exception(wxwork_finance_sdk_exception_ce, "GetMediaData error", ret); return; } fwrite(GetData(media_data), GetDataLen(media_data), 1, fp); }while(IsMediaDataFinish(media_data) != 1); fclose(fp); FreeMediaData(media_data); RETURN_TRUE; } PHP_METHOD(WxworkFinanceSdk, getMediaData) { zend_string *sdk_filedid, *index_buf; if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &sdk_filedid, &index_buf) == FAILURE) { return; } zval *this = getThis(); // zend_class_entry *ce = Z_OBJCE_P(this); ze_WeWorkFinanceSdk_object *ce = Z_OBJCE_P(this); zval *proxy_host_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_proxy_host", sizeof("_proxy_host") - 1, 0, NULL); zval *proxy_password_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_proxy_password", sizeof("_proxy_password") - 1, 0, NULL); zval *timeout_zval = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), "_timeout", sizeof("_timeout") - 1, 0, NULL); MediaData_t *media_data = NewMediaData(); if (NULL == media_data) { zend_error(E_ERROR, "There is not enough memory!"); return; } WeWorkFinanceSdk_t *wecom_sdk = wxwork_finance_internal_get_sdk(this); int ret = GetMediaData(wecom_sdk, ZSTR_VAL(index_buf), ZSTR_VAL(sdk_filedid), Z_STRVAL_P(proxy_host_zval), Z_STRVAL_P(proxy_password_zval), zval_get_long(timeout_zval), media_data); if (0 != ret) { zend_throw_exception(wxwork_finance_sdk_exception_ce, "GetMediaData error", ret); return; } array_init(return_value); add_assoc_stringl(return_value, "data", GetData(media_data), GetDataLen(media_data)); add_assoc_string(return_value, "nextIndex", GetOutIndexBuf(media_data)); add_assoc_bool(return_value, "isFinished", IsMediaDataFinish(media_data) == 1 ? 1 : 0); //RETURN_STRINGL(GetData(media_data), GetDataLen(media_data)); FreeMediaData(media_data); } /* }}} */ static const zend_function_entry wxwork_finance_sdk_class_methods[] = { PHP_ME(WxworkFinanceSdk, __construct, arginfo_class_WxworkFinanceSdk___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_ME(WxworkFinanceSdk, getChatData, arginfo_class_WxworkFinanceSdk_getChatData, ZEND_ACC_PUBLIC) PHP_ME(WxworkFinanceSdk, decryptData, arginfo_class_WxworkFinanceSdk_decryptData, ZEND_ACC_PUBLIC) PHP_ME(WxworkFinanceSdk, downloadMedia, arginfo_class_WxworkFinanceSdk_downloadMedia, ZEND_ACC_PUBLIC) PHP_ME(WxworkFinanceSdk, getMediaData, arginfo_class_WxworkFinanceSdk_getMediaData, ZEND_ACC_PUBLIC) PHP_FE_END }; static const zend_function_entry wxwork_finance_sdk_exception_methods[] = { PHP_FE_END }; /* {{{ PHP_INI */ /* Remove comments and fill if you need to have entries in php.ini PHP_INI_BEGIN() STD_PHP_INI_ENTRY("wxwork_finance_sdk.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_wxwork_finance_sdk_globals, wxwork_finance_sdk_globals) STD_PHP_INI_ENTRY("wxwork_finance_sdk.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_wxwork_finance_sdk_globals, wxwork_finance_sdk_globals) PHP_INI_END() */ /* }}} */ /* Remove the following function when you have successfully modified config.m4 so that your module can be compiled into PHP, it exists only for testing purposes. */ /* Every user-visible function in PHP should document itself in the source */ /* {{{ proto string confirm_wxwork_finance_sdk_compiled(string arg) Return a string to confirm that the module is compiled in */ PHP_FUNCTION(confirm_wxwork_finance_sdk_compiled) { char *arg = NULL; size_t arg_len, len; zend_string *strg; if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { return; } strg = strpprintf(0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "wxwork_finance_sdk", arg); RETURN_STR(strg); } /* }}} */ /* The previous line is meant for vim and emacs, so it can correctly fold and unfold functions in source code. See the corresponding marks just before function definition, where the functions purpose is also documented. Please follow this convention for the convenience of others editing your code. */ /* {{{ php_wxwork_finance_sdk_init_globals */ /* Uncomment this function if you have INI entries static void php_wxwork_finance_sdk_init_globals(zend_wxwork_finance_sdk_globals *wxwork_finance_sdk_globals) { wxwork_finance_sdk_globals->global_value = 0; wxwork_finance_sdk_globals->global_string = NULL; } */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(wxwork_finance_sdk) { /* If you have INI entries, uncomment these lines REGISTER_INI_ENTRIES(); */ // define WxworkFinanceSdkException zend_class_entry wxwork_finance_sdk_exception_def; INIT_CLASS_ENTRY(wxwork_finance_sdk_exception_def, "WxworkFinanceSdkException", wxwork_finance_sdk_exception_methods); wxwork_finance_sdk_exception_ce = zend_register_internal_class_ex(&wxwork_finance_sdk_exception_def, zend_ce_exception); zend_class_entry wxwork_finance_sdk_def; INIT_CLASS_ENTRY(wxwork_finance_sdk_def, "WxworkFinanceSdk", wxwork_finance_sdk_class_methods); wxwork_finance_sdk_ce = zend_register_internal_class(&wxwork_finance_sdk_def); zend_declare_property_string(wxwork_finance_sdk_ce, "_corpId", sizeof("_corpId") - 1, "", ZEND_ACC_PRIVATE); zend_declare_property_string(wxwork_finance_sdk_ce, "_secret", sizeof("_secret") - 1, "", ZEND_ACC_PRIVATE); // http proxy zend_declare_property_string(wxwork_finance_sdk_ce, "_proxy_host", sizeof("_proxy_host") - 1, "", ZEND_ACC_PRIVATE); zend_declare_property_string(wxwork_finance_sdk_ce, "_proxy_password", sizeof("_proxy_password") - 1, "", ZEND_ACC_PRIVATE); // request timeout zend_declare_property_long(wxwork_finance_sdk_ce, "_timeout", sizeof("_timeout") - 1, WXWORK_SDK_DEFAULT_TIMEOUT, ZEND_ACC_PRIVATE); // declare wecom finance sdk zend_declare_property_null(wxwork_finance_sdk_ce, WXWORK_SDK_G_NAME, WXWORK_SDK_G_NAME_SIZE, ZEND_ACC_PRIVATE); return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(wxwork_finance_sdk) { /* uncomment this line if you have INI entries UNREGISTER_INI_ENTRIES(); */ return SUCCESS; } /* }}} */ /* Remove if there's nothing to do at request start */ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(wxwork_finance_sdk) { #if defined(COMPILE_DL_WXWORK_FINANCE_SDK) && defined(ZTS) ZEND_TSRMLS_CACHE_UPDATE(); #endif return SUCCESS; } /* }}} */ /* Remove if there's nothing to do at request end */ /* {{{ PHP_RSHUTDOWN_FUNCTION */ PHP_RSHUTDOWN_FUNCTION(wxwork_finance_sdk) { return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(wxwork_finance_sdk) { php_info_print_table_start(); php_info_print_table_header(2, "wxwork_finance_sdk support", "enabled"); php_info_print_table_end(); /* Remove comments if you have entries in php.ini DISPLAY_INI_ENTRIES(); */ } /* }}} */ /* {{{ wxwork_finance_sdk_functions[] * * Every user visible function must have an entry in wxwork_finance_sdk_functions[]. */ const zend_function_entry wxwork_finance_sdk_functions[] = { PHP_FE(confirm_wxwork_finance_sdk_compiled, arginfo_confirm_wxwork_finance_sdk_compiled) /* For testing, remove later. */ PHP_FE_END /* Must be the last line in wxwork_finance_sdk_functions[] */ }; /* }}} */ /* {{{ wxwork_finance_sdk_module_entry */ zend_module_entry wxwork_finance_sdk_module_entry = { STANDARD_MODULE_HEADER, "wxwork_finance_sdk", wxwork_finance_sdk_functions, PHP_MINIT(wxwork_finance_sdk), PHP_MSHUTDOWN(wxwork_finance_sdk), PHP_RINIT(wxwork_finance_sdk), /* Replace with NULL if there's nothing to do at request start */ PHP_RSHUTDOWN(wxwork_finance_sdk), /* Replace with NULL if there's nothing to do at request end */ PHP_MINFO(wxwork_finance_sdk), PHP_WXWORK_FINANCE_SDK_VERSION, STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_WXWORK_FINANCE_SDK #ifdef ZTS ZEND_TSRMLS_CACHE_DEFINE() #endif ZEND_GET_MODULE(wxwork_finance_sdk) #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */
php_wxwork_finance_sdk.h 文件
/* $Id$ */ #ifndef PHP_WXWORK_FINANCE_SDK_H #define PHP_WXWORK_FINANCE_SDK_H extern zend_module_entry wxwork_finance_sdk_module_entry; #define phpext_wxwork_finance_sdk_ptr &wxwork_finance_sdk_module_entry #define PHP_WXWORK_FINANCE_SDK_VERSION "0.1.0" /* Replace with version number for your extension */ #ifdef PHP_WIN32 # define PHP_WXWORK_FINANCE_SDK_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 # define PHP_WXWORK_FINANCE_SDK_API __attribute__ ((visibility("default"))) #else # define PHP_WXWORK_FINANCE_SDK_API #endif #ifdef ZTS #include "TSRM.h" #endif /* Declare any global variables you may need between the BEGIN and END macros here: ZEND_BEGIN_MODULE_GLOBALS(wxwork_finance_sdk) zend_long global_value; char *global_string; ZEND_END_MODULE_GLOBALS(wxwork_finance_sdk) */ /* Always refer to the globals in your function as WXWORK_FINANCE_SDK_G(variable). You are encouraged to rename these macros something shorter, see examples in any other php module directory. */ #define WXWORK_FINANCE_SDK_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(wxwork_finance_sdk, v) #if defined(ZTS) && defined(COMPILE_DL_WXWORK_FINANCE_SDK) ZEND_TSRMLS_CACHE_EXTERN() #endif #include "zend_exceptions.h" #include "ext/spl/spl_exceptions.h" #include "WeWorkFinanceSdk_C.h" #define TRACE(fmt, ...) do { trace(__FILE__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__); } while (0) static inline void trace(const char *file, int line, const char* function, const char *fmt, ...) { fprintf(stderr, "%s(%s:%d) - ", function, file, line); va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); } #define WXWORK_SDK_G_NAME "_wecomSDK" #define WXWORK_SDK_G_NAME_SIZE sizeof(WXWORK_SDK_G_NAME) - 1 // 默认超时时间 #define WXWORK_SDK_DEFAULT_TIMEOUT 30 #define WXWORK_FINANCE_OBJ_P(zobj) Z_OBJ_P(zobj) typedef struct _ze_WeWorkFinanceSdk_object { char *_corpId; char *_secret; char *_proxy_host; char *_proxy_password; char *_timeout; char *_wecomSDK; zend_object zo; }ze_WeWorkFinanceSdk_object; #endif /* PHP_WXWORK_FINANCE_SDK_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */
wxwork_finance_arginfo.h
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_WxworkFinanceSdk___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, corp_id, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, secret, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, option, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_WxworkFinanceSdk_getChatData, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, seq, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, limit, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_WxworkFinanceSdk_decryptData, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, randomKey, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, encryptStr, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_WxworkFinanceSdk_getMediaData, 0, 2, SplFileInfo, 0) ZEND_ARG_TYPE_INFO(0, sdkFileId, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, ext, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_WxworkFinanceSdk_downloadMedia, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, filedId, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, saveTo, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_WxworkFinanceSdk_getDecryptChatData, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, seq, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, limit, IS_LONG, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_confirm_wxwork_finance_sdk_compiled, 0, 0, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, arg, IS_STRING, 0) ZEND_END_ARG_INFO()
六、注意点:
Z_OBJ_P 和 Z_OBJCE_P 都是 Zend 引擎的宏定义。
Z_OBJ_P 是一个宏定义,用于获取指向 zval 结构体中对象实例的指针。可以使用该宏来访问和操作对象实例的属性或方法。
Z_OBJCE_P 是一个宏定义,用于获取指向 zval 结构体中对象类的指针。可以使用该宏来获取对象所属的类名、调用类的静态方法等。
因此,它们的区别在于,Z_OBJ_P 用于操作对象实例本身,Z_OBJCE_P 用于操作对象所属的类。
七、关于centos 8.x php安装会话存档sdk出现free(): invalid pointer,需要在php编译安装时禁止安装init , --disable-intl参考链接(https://zhuanlan.zhihu.com/p/374494351?utm_id=0)