php zend引擎api接口:ZENDAPI阅读,反射调用示例
php
zend
反射
api
编程技术
发布日期
2023-06-07
更新日期
2023-06-07
阅读次数 134
文章字数 1.9k
ZENDAPI是zend引擎封装的api,方便C语言调用,在开发php扩展时非常有用。
查看ZENDAPI接口
下载php源码,在github克隆一份php-src源码即可【注意切换分支到所需版本】
在根目录/zend/zend_API.h中,定义了大量的宏,这些宏可以直接在任意地方调用而无需引入头文件。
以调用php反射调用函数示例,调用指定名称的php函数call_user_function
查阅zend_API.h可以看到如下内容:
ZEND_API zend_result _call_user_function_impl(zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], HashTable *named_params);
#define call_user_function(function_table, object, function_name, retval_ptr, param_count, params)
_call_user_function_impl(object, function_name, retval_ptr, param_count, params, NULL)
#define call_user_function_named(function_table, object, function_name, retval_ptr, param_count, params, named_params)
_call_user_function_impl(object, function_name, retval_ptr, param_count, params, named_params)
参数分析:
根据经验,function_table一般是CG(function_table)或者EG(function_table),
object表示对象,如果只是普通函数则该参数传递NULL,否则传递指定的zend_object
function_name表示参数名,是zval *类型
retval_ptr表示zval *类型的指针,表示返回值引用
param_count表示参数数量
params则表示zval数组
调用var_dump示例:
{
//函数名
zval funName;
ZVAL_STRING(&funName, "var_dump"); //函数名是一个callable,可以是字符串或者数组,这里是字符串,例如myClass::test等方式也支持
//返回值
zval retVal;
//构造参数数组
zval params[2];
ZVAL_LONG(¶ms[0],100);
ZVAL_STRING(¶ms[1], "字符串");
//反射调用函数
call_user_function(EG(function_table),NULL,&funName,&retVal,2,params);
}
相当于php代码:var_dump(100,"字符串");
反射调用对象示例
前面举例了一个反射调用var_dump,这里再举例一个反射调用对象静态方法、实例方法
php代码:
<?php
function returnData(){
return DB::sql("select * from user")->selectArrList();
}
C扩展里,并没有这种链式结构,所以第一次先反射静态方法DB::sql得到DB对象,然后用db->selectArrList(),C代码如下:
{
//函数名 ["DB","sql"]
zval funName;
array_init(&funName);
add_next_index_string(&funName,"DB");
add_next_index_string(&funName,"sql");
//返回值
zval dbObj;
//构造参数数组
zval params[1];
ZVAL_STRING(¶ms[0], "select * from `user`");
//反射调用静态函数
call_user_function(EG(function_table),NULL,&funName,&dbObj,1,params);
// php_var_dump(&dbObj,0);
//根据object,再次调用selectArrList()参数
zval funName2;
array_init(&funName2);
add_next_index_zval(&funName2,&dbObj);
add_next_index_string(&funName2,"selectArrList");
zval retDataArr;
//反射调用实例函数
call_user_function(EG(function_table),NULL,&funName2,&retDataArr,0,NULL);
RETURN_ARR(Z_ARR_P(&retDataArr));
}
文章作者: 朱丰华
文章链接: https://smart.52dixiaowo.com/blog/post-430.html
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。
php
zend
反射
api
发表评论
相关推荐