实际应用中,扩展可能需要调用用户自定义的函数或者其他扩展定义的内部函数,PHP提供的函数调用API的使用:

ZEND_API int call_user_function(HashTable *function_table, zval *object,zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[
]);

各参数的含义:

__function_table:__ 函数符号表,普通函数是EG(function_table),如果是成员方法则是zend_class_entry.function_table
object: 调用成员方法时的对象
__function_name:__ 调用的函数名称
__retval_ptr:__ 函数返回值地址
__param_count:__ 参数数量
params: 参数数组
从接口的定义看其使用还是很简单的,不需要我们关心执行过程中各阶段复杂的操作。下面从一个具体的例子看下其使用:

(1)在PHP中定义了一个普通的函数,将参数$i加上100后返回:

function mySum($i){return $i+100;
}

(2)接下来在扩展中调用这个函数:

PHP_FUNCTION(my_func_2)
{zend_long i;zval call_func_name, call_func_ret, call_func_params[1];uint32_t call_func_param_cnt = 1;zend_string *call_func_str;char *func_name = "mySum";if(zend_parse_parameters(ZEND_NUM_ARGS(), "l", &i) == FAILURE){RETURN_FALSE;}//分配zend_string:调用完需要释放call_func_str = zend_string_init(func_name, strlen(func_name), 0);//设置到zvalZVAL_STR(&call_func_name, call_func_str);//设置参数ZVAL_LONG(&call_func_params[0], i);//callif(SUCCESS != call_user_function(EG(function_table), NULL, &call_func_name, &call_func_ret, call_func_param_cnt, call_func_params)){zend_string_release(call_func_str);RETURN_FALSE;}zend_string_release(call_func_str);RETURN_LONG(Z_LVAL(call_func_ret));
}

(3)最后调用这个内部函数:

function mySum($i){return $i+100;
}
echo my_func_2(60);
===========[output]===========
160

call_user_function() 并不是只能调用PHP脚本中定义的函数,内核或其它扩展注册
的函数同样可以通过此函数调用,比如:array_merge()。

PHP_FUNCTION(my_func_1)
{zend_array *arr1, *arr2;zval call_func_name, call_func_ret, call_func_params[2];uint32_t call_func_param_cnt = 2;zend_string *call_func_str;char *func_name = "array_merge";if(zend_parse_parameters(ZEND_NUM_ARGS(), "hh", &arr1, &arr2) == FAILURE){RETURN_FALSE;}//分配zend_stringcall_func_str = zend_string_init(func_name, strlen(func_name), 0);//设置到zvalZVAL_STR(&call_func_name, call_func_str);ZVAL_ARR(&call_func_params[0], arr1);ZVAL_ARR(&call_func_params[1], arr2);if(SUCCESS != call_user_function(EG(function_table), NULL, &call_func_name, &call_func_ret, call_func_param_cnt, call_func_params)){zend_string_release(call_func_str);RETURN_FALSE;}zend_string_release(call_func_str);RETURN_ARR(Z_ARRVAL(call_func_ret));
}
$arr1 = array(1,2);
$arr2 = array(3,4);
$arr = my_func_1($arr1, $arr2);
var_dump($arr);

【php7扩展开发五】函数调用相关推荐

  1. php获取字符串扩展,PHP7扩展开发之字符串处理

    标签: 本文和大家分享的主要是PHP7扩展开发中字符串的处理相关知识,希望通过本文的分享能帮助大家更好的学习php. 这次,我们来看看字符串在PHP扩展里面如何处理. 示例代码如下: $len = s ...

  2. php7扩展开发教程,Linux下PHP7扩展开发入门教程1:扩展开发流程

    本文将会基于PHP7开发一个最简单的扩展,随便取个名learn_ext,编译生成一个learn_ext.so文件,最终调用可以在php中调用learn_ext扩展中的函数来输出一个hello worl ...

  3. php7扩展开发教程,Laravel 7 扩展开发教程

    下面由Laravel入门教程栏目给大家介绍Laravel 7 扩展开发教程,希望对需要的朋友有所帮助! 步骤 1. 创建一个新项目 我更喜欢使用 Laravel 安装程序.laravel new la ...

  4. 【php7扩展开发六】zval的操作

    生成各类型zval PHP7将变量的引用计数转移到了具体的value上,所以zval更多的是作为统一的传输格式,很多情况下只是临时性使用,比如函数调用时的传参,最终需要的数据是zval携带的zend_ ...

  5. 【php7扩展开发四】函数的参数 ,引用传参 ,返回值

    函数参数解析 之前我们定义的函数没有接收任何参数,那么扩展定义的内部函数如何读取参数呢?用户自定义函数在编译时会为每个参数创建一个zend_arg_info结构,这个结构用来记录参数的名称.是否引用传 ...

  6. 【php7扩展开发一】注册一个内部函数hello world

    通过扩展可以将C语言实现的函数提供给PHP脚本使用,如同大量PHP内置函数一样,这些函数统称为内部函数(internal function),与PHP脚本中定义的用户函数不同,它们无需精力用户函数的编 ...

  7. 【php7扩展开发二】全局变量

    使用C语言开发程序时经常会使用全局变量进行数据存储,这就涉及前面已经介绍过的一个问题:线程安全,PHP设计了TSRM(即:线程安全资源管理器)用于解决这个问题,内核中频繁使用到的EG.CG等都是根据是 ...

  8. PHP7扩展开发(二):配置项与全局数值

    起步 Zend引擎提供了另种管理设置值(INI)的途径.现在弄个简单的,我们经常看到php.ini里有诸如 display_errors = On 这样的全局设置.假设我们需要为我们扩展定义一个值: ...

  9. 【php7扩展开发三】ini配置

    php.ini配置 php.ini是PHP主要的配置文件,解析时PHP将在这些地方依次查找该文件:当前工作目录.环境变量PHPRC指定目录.编译时指定的路径,在命令行模式下,php.ini的查找路径可 ...

最新文章

  1. 【Python入门】你值得拥有的这八个实用工具安装包与实战项目
  2. Linux C编程--进程间通信(IPC)3--信号集和发送信号介绍
  3. css样式继承规则详解
  4. javascript箭头函数和this的指向问题
  5. 使用Visio Viewer载入数据库中的Visio图
  6. PP视频怎么设置退出程序时清空本地播放记录
  7. 笔记10:时时屏幕抓取小程序
  8. 第十四节:ES6的 Iterator 遍历器到底是什么?
  9. 硅谷大佬提前剧透未来!6本书,助你走在AI时代前沿
  10. ios项目中使用gcd的场景_iOS中超级超级详细介绍GCD
  11. 学java用什么编译器_学习Java用什么编译软件好
  12. 《网络是怎样连接的》笔记
  13. python xlwt写excel_Python使用xlwt写excel并设置写入格式
  14. selenium + 超级鹰 识别验证码自动登录
  15. png能转换成html吗,png转化成pdf
  16. 27 | 风控系统:如何从海量业务数据中,挖掘黑灰产?
  17. 【IoT】创业:产品生产之老化测试
  18. 豆瓣评分8.5+,这10本好书,不读你就OUT了
  19. 解决“windows已经阻止此软件因为无法验证发行者”方法
  20. Windows 程序设计

热门文章

  1. matlab求矩阵中值函数,matlab在一个函数里,如何调用另一个函数里面求得的雅可比矩阵并赋值?...
  2. 01. elastcsearch-monitor (es 监控)
  3. 蓝桥杯 ALGO-21 算法训练 装箱问题
  4. 通俗易懂!navicate如何导入MySQL数据库的.sql文件?
  5. python readlines慢_为什么readline()比Python中的readlines()慢得多?
  6. Apache连接和访问控制
  7. 手工搭建APACHE服务
  8. Linux KVM 虚拟化技术
  9. Redis数据库(四)——Redis集群模式(主从复制、哨兵、Cluster)
  10. mybatis mysql查询树形结构_MyBatis collection 集合嵌套查询树形节点