Skip to content

Commit 1de9b7a

Browse files
committed
update
1 parent 8537fc6 commit 1de9b7a

File tree

1 file changed

+41
-4
lines changed

1 file changed

+41
-4
lines changed

7/func.md

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,24 +396,61 @@ ZEND_END_ARG_INFO()
396396
//声明为可变参数
397397
#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) { #name, NULL, 0, pass_by_ref, 0, 1 },
398398
```
399-
399+
举个例子来看:
400+
```php
401+
function my_func_1(&$a, Exception $c){
402+
...
403+
}
404+
```
405+
用内核实现则可以这么定义:
406+
```c
407+
ZEND_BEGIN_ARG_INFO_EX(arginfo_my_func_1, 0, 0, 1)
408+
ZEND_ARG_INFO(1, a) //引用
409+
ZEND_ARG_OBJ_INFO(0, b, Exception, 0) //注意:这里不要把字符串加""
410+
ZEND_END_ARG_INFO()
411+
```
400412
展开后:
401413
```c
402414
static const zend_internal_arg_info name[] = {
403415
{ (const char*)(zend_uintptr_t)(2), NULL, 0, 0, 0, 0 },
404-
{ name, NULL, 0, 0, 0, 0 },
405-
{ id, NULL, 0, 1, 0, 0 },
416+
{ "a", NULL, 0, 0, 0, 0 },
417+
{ "b", "Exception", 8, 1, 0, 0 },
406418
}
407419
```
408-
第一个数组元素用于记录必传参数的数量以及返回值是否为引用。定义完这个数组接下来就需要把这个数组告诉函数`PHP_FE()`宏的第二个参数就是接收这个数组的
420+
第一个数组元素用于记录必传参数的数量以及返回值是否为引用。定义完这个数组接下来就需要把这个数组告诉函数:
409421
```c
410422
const zend_function_entry mytest_functions[] = {
411423
PHP_FE(my_func_1, arginfo_my_func_1)
412424
PHP_FE(my_func_2, NULL)
413425
PHP_FE_END //末尾必须加这个
414426
};
415427
```
428+
引用参数通过`zend_parse_parameters()`解析时只能使用"z"解析,不能再直接解析为zend_value了,否则引用将失效:
429+
```
430+
PHP_FUNCTION(my_func_1)
431+
{
432+
zval *lval; //必须为zval,定义为zend_long也能解析出,但不是引用
433+
zval *obj;
416434
435+
if(zend_parse_parameters(ZEND_NUM_ARGS(), "zo", &lval, &obj) == FAILURE){
436+
RETURN_FALSE;
437+
}
438+
439+
//lval的类型为IS_REFERENCE
440+
zval *real_val = Z_REFVAL_P(lval); //获取实际引用的zval地址:&(lval.value->ref.val)
441+
Z_LVAL_P(real_val) = 100; //设置实际引用的类型
442+
}
443+
```
444+
```php
445+
$a = 90;
446+
$b = new Exception;
447+
my_func_1($a, $b);
448+
449+
echo $a;
450+
==========[output]===========
451+
100
452+
```
453+
> __Note:__ 参数数组与zend_parse_parameters()有很多功能重合,两者都会生效,对zend_internal_arg_info验证在zend_parse_parameters()之前,为避免混乱两者应该保持一致;另外,虽然内部函数的参数数组并不强制定义声明,但还是建议声明。
417454
418455
### 7.6.4 函数返回值
419456

0 commit comments

Comments
 (0)