php的自定义函数返回值,php自定义函数返回值的用法详解

本文详细解析了PHP用户空间函数如何通过return关键字返回值,与C语言的对比,并介绍了内部处理机制。重点讲解了return_value变量的使用,强调了不应直接分配和返回zval*,而应直接修改return_value的值。最后展示了如何在PHP扩展中添加新函数并进行测试。
摘要由CSDN通过智能技术生成

返回值

用户空间函数利用return关键字向它的调用空间回传信息, 这一点和C语言的语法相同.

例如:function sample_long() {

return 42;

}

$bar = sample_long();

当sample_long()被调用时, 返回42并设置到$bar变量中. 在C语言中的等价代码如下:int sample_long(void) {

return 42;

}

void main(void) {

int bar = sample_long();

}

当然, 在C语言中你总是知道被调用的函数是什么, 并且基于函数原型返回, 因此相应的你要定义返回结果存储的变量. 在php用户空间处理时, 变量类型是动态的, 转而依赖于第2章"变量的里里外外"中介绍的zval的类型.

return_value变量

你可能认为你的内部函数应该直接返回一个zval, 或者说分配一个zval的内存空间并如下返回zval *.PHP_FUNCTION(sample_long_wrong)

{

zval *retval;

MAKE_STD_ZVAL(retval);

ZVAL_LONG(retval, 42);

return retval;

}

不幸的是, 这样做是不正确的. 并不是强制每个函数实现分配zval并返回它. 而是Zend引擎在函数调用之前预先分配这个空间. 接着将zval的类型初始化为IS_NULL, 并将值作为参数名return_value传递. 下面是正确的做法:PHP_FUNCTION(sample_long)

{

ZVAL_LONG(return_value, 42);

return;

}

要注意的是PHP_FUNCTION()实现并不会直接返回任何值. 取而代之的是直接将恰当的数据弹出到return_value参数中, Zend引擎会在内部函数执行完成后处理它.

友情提示: ZVAL_LONG()宏是对多个赋值操作的一个封装:Z_TYPE_P(return_value) = IS_LONG;

Z_LVAL_P(return_value) = 42;

或者更直接点:return_value->type = IS_LONG;

return_value->value.lval = 42;

return_value的is_ref和refcount属性不应该被内部函数直接修改. 这些值由Zend引擎在调用你的函数时初始化并处理.

现在我们来看看这个特殊的函数, 将它增加到第5章"你的第一个扩展"中创建的sample扩展中. 只需要在sample_hello_world()函数下面添加这个函数, 并将sample_long()加入到php_sample_functions结构体中:static function_entry php_sample_functions[] = {

PHP_FE(sample_hello_world, NULL)

PHP_FE(sample_long, NULL)

{ NULL, NULL, NULL }

};

现在我们就可以执行make重新构建扩展了.

如果一切OK, 可以运行php并测试新函数:

$ php -r 'var_dump(sample_long());

包装更紧凑的宏

在代码可读性和可维护性方面, ZVAL_*()宏中有重复的部分: return_value变量. 这种情况下, 将宏的ZVAL替换为RETVAL, 我们就可以在调用时省略return_value了.

前面的例子中, sample_long()的实现代码可以缩减到下面这样:PHP_FUNCTION(sample_long)

{

RETVAL_LONG(42);

return;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值