[李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的参数
来源:互联网 发布:餐饮大数据分析报告 编辑:程序博客网 时间:2024/05/21 10:14
函数的参数
上回书说到:函数的定义是一个将函数名注册到函数列表的过程。
函数的参数检查是通过zend_do_receive_arg函数实现的。
用户自定义函数的参数
在zend_do_receive_arg函数中对于参数的关键代码如下:
CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];cur_arg_info->name estrndup(varname->u.constant.value.str.val,varname->u.constant.value.str.len);cur_arg_info->name_len = varname->u.constant.value.str.len;cur_arg_info->array_type_hint = 0;cur_arg_info->allow_null = 1;cur_arg_info->pass_by_reference = pass_by_reference;cur_arg_info->class_name = NULL;cur_arg_info->class_name_len = 0;
整个参数的传递是通过给中间代码的arg_info字段执行赋值操作完成。关键点是在arg_info字段。
字段的结构如下:
typedef struct _zend_arg_info{ const char *name;// 参数的名称 zend_uint name_len;//参数名称的长度 const char *class_name;//类名 zend_uint class_name_len;//类名长度 zend_bool array_type_hint;//数组类型提示 zend_bool allow_null;//是否允许为NULL zend_bool pass_by_reference;//是否引用传递 zend_bool return_reference; int required_num_args;}zend_arg_info;
参数的值传递和参数传递的区分是通过pass_by_reference参数在生成中间代码时实现的。
在实际编程中我们可能会遇到可变参数。
func_num_args;func_get_args;
其中 func_num_args的内部实现如下:
位于 Zend/zend_builtin_functions.c文件中
ZEND_FUNCTION(func_num_args){ zend_execute_data *ex = EG(current_execute_data)->prev_execute_data; if(ex & ex->function_state.arguments){ RETURN_LONG((long)(zend_uinptr_t)*(ex->function_state.arguments)); }else{ zend_error(E_WARNING,"func_num_args(); called from the global scope no function context"); RETURN_LONG(-1); }}
另外的一个函数也是一样的。关键在于在 current_execute_data 进行执行。
内部函数的参数
PHP_FUNCTION(count){ zval *array; long mode = COUNT_NORMAL; if(zend_parse_parameters(ZEND_NUM_ARGSS) TSRMLS_CC,"z|l", &array,&node) == FAILURE){ return ; }}
两个关键点:
一个是取参数的个数,一个是解析参数列表。
取参数的个数是通过ZEND_NUM_ARGS()宏来实现。
\#define ZEND_NUM_ARGS() (ht)
ht是在 Zend/zend.h文件中定义的宏 INTERNAL_FUNCTION_PARAMETERS中的ht,如下:
解析参数列表
php内部函数在解析参数时使用的是zend_parse_parameters.它可以大大简化参数的接收处理工作,虽然它在处理可变参数时还有点弱。
其声明如下:
ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec)
第一个参数:num_args表明示想要接收的参数个数,我们经常使用ZEND_NUM_ARGS()来表示对传入的参数”有多少要多少”
第二个参数:是宏TSRMLS_CC.
第三个参数:type_spec是一个字符串,用来指定我们所期待接收的各个参数的类型,有点类似于printf中指定输出格式的那个格式化字符串。
剩下的参数就是我们用来接收PHP参数值的变量指针。
参数的传递
function do_something($s){ xdebug_debug_zval('s'); $s = 100; return $s;}$a = 1111;$b = do_something($a);echo $b;
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的参数-1
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的参数
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数间的转换
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的定义
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的返回值
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --简介
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的调用和执行
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --匿名函数及闭包
- 深入理解PHP内核[读书笔记]--第四章:函数的实现 --匿名函数及闭包
- [李景山php] 深入理解PHP内核[读书笔记]--第二章:用户代码执行--opcode处理函数查找
- [李景山php] 深入理解PHP内核[读书笔记]--第二章:用户代码执行--PHP脚本的执行
- [李景山php] 深入理解PHP内核[读书笔记]--第五章:类和面向对象 --类的结构和实现
- [李景山php] 深入理解PHP内核[读书笔记]--第五章:类和面向对象 --访问控制的实现
- [李景山php] 深入理解PHP内核[读书笔记]--第三章:变量及数据类型--变量的生命周期
- [李景山php] 深入理解PHP内核[读书笔记]--第三章:变量及数据类型--变量的作用域
- [李景山php] 深入理解PHP内核[读书笔记]--第三章:变量及数据类型--变量的结构和类型--PHP的哈希实现
- [李景山php] 深入理解PHP内核[读书笔记]--第二章:用户代码执行--PHP脚本的执行 词法分析和语法分析
- [李景山php] 深入理解PHP内核[读书笔记]--第三章:变量及数据类型--变量的结构和类型--类型提示的实现
- java 微信自定义菜单 java微信接口开发 公众平台 SSM
- Spring源码学习第二节
- Java 泛型 <? super T> 中 super 怎么 理解?与 extends 有何不同?
- Ubuntu下如何解压缩zip,tar,tar.gz,tar.bz2文件
- oracle ODI-20161:标准逆向工程失败
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --函数的参数
- 流媒体学习笔记(一)
- Java操作wkhtmltopdf实现Html转PDF
- eclipse 下ndk开发
- win7旗舰版,KB4012212安装失败问题:
- 两个数据库比较 对比视图存储过程及表结构差异
- 无向图中基于宽度优先搜索的求两个节点间的最短跳数
- tf.nn.sparse_softmax_cross_entropy_with_logits的用法
- 记住上次的滚动条的位置,下次打开直接在哪个位置