php扩展 call_user_function,[php-src]扩展中封装业务与 call_user_function 的使用建议

内容均以php5.6.14为例.

从一个封装 uniqid 的例子来讲。

/*{{{ wrapper of uniqid*/PHP_FUNCTION(fox)

{

// #1.

zval*prefix, *more = NULL;

zval function,*params[2] = {0};//#2.

if ( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &prefix, &more) ==FAILURE ) {RETURN_FALSE;

}params[0] =prefix;if(more) {params[1] =more;

}//#3.

ZVAL_STRING(&function, "uniqid", 0);// #4.

if ( call_user_function(EG(function_table), NULL, &function, return_value, ZEND_NUM_ARGS(), params TSRMLS_CC) ==FAILURE ) {if(return_value) {

zval_dtor(return_value);

}

zend_error(E_WARNING,"%s() calling %s() failed.", get_active_function_name(TSRMLS_C), Z_STRVAL(function));

RETURN_FALSE;

}

RETURN_STRING(Z_STRVAL_P(return_value),0);

}/*}}}*/

#1.

zval 不赋值默认是非空,不要随意给 声明的 zval 赋值为 NULL,除非你知道自己在干什么,比方用在判断是否有传参;

如果你想对可选的参数使用默认值 farwish,可以像下面这样 (非用于上例):

if (more ==NULL) {

MAKE_STD_ZVAL(more);

Z_STRVAL_P(more)= "farwish";

Z_STRLEN_P(more)= strlen("farwish");

Z_TYPE_P(more)=IS_STRING;

}params[1] = more;

还有别忘了 call_user_function 中的参数个数就不能再用 ZEND_NUM_ARGS(),写固定值 2 就可以了。

#2.

接收的参数类型必须用双引号包裹,为了避免其它地方也遇到这种错误,最好后面统一都用双引号。

如果接收的参数含 char *name 类型的, 别忘了要有 uint *len 跟在它后面传入。

#3. #4.

如果开头声明的是 zval *function, 并且 ZVAL_STRING 赋值 和 call_user_function 的调用都传 function, 编译能通过, 但是使用会segmentaion fault;测试证明, ZVAL_STRING 第一个参数一定是指向 zval 的地址, 而不是简单的传 zval *, 因为宏中做了 zval *__z = (z) 这么一件事, 如果 z 已经是指针, 那么值就不对了.

Thats all.

@黑眼诗人  

原文:http://www.cnblogs.com/farwish/p/5635429.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值