多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 7.2 函数的参数 在前面的章节中我们已经介绍过arg info了,下面我们看一下如何通过其实现类型绑定,但这个特性只能在Zend Engine 2也就是PHP5中使用。 让我们再回顾一下ZE2's argument info结构。每一个arg info结构的声明都是通过ZEND_BEGIN_ARG_INFO()或者ZEND_BEGIN_ARG_INFO_EX()宏函数开始的,然后紧跟着几行ZEND_ARG_*INFO()宏函数,最终以ZEND_END_ARG_INFO()宏函数结束。每个宏的基本作用我们可以在第6章的最后一节看到。如果我们想重写一下PHP语言中的count()函数,可以: ````c ZEND_FUNCTION(sample_count_array) { zval *arr; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a",&arr) == FAILURE) { RETURN_NULL(); } RETURN_LONG(zend_hash_num_elements(Z_ARRVAL_P(arr))); } ```` zend_parse_parameters()本身可以保证传递过来的参数是一个数组。但是如果我们通过zend_get_parameter()函数来接收参数的话就没这么幸运了,需要我们自己进行类型校对。如果想让内核自动完成类型校对,便需要arg_info上场了: ````c ZEND_BEGIN_ARG_INFO(php_sample_array_arginfo, 0) ZEND_ARG_ARRAY_INFO(0, arr, 0) ZEND_END_ARG_INFO() .... PHP_FE(sample_count_array, php_sample_array_arginfo) .... ```` 这样我们便把类型校对的工作交给了Zend Engine,是不是有种如释重负的感觉!You've also given your argument a name so that the generated error messages can be more meaningful to script writers attempting to use your API. 我们同样可以对参数中的对象进行校验,限制其是继承自某个类或者实现了某个接口等等。 ````c ZEND_BEGIN_ARG_INFO(php_sample_class_arginfo, 0) ZEND_ARG_OBJ_INFO(1, obj, stdClass, 0) ZEND_END_ARG_INFO() ```` 需要注意的是,此时第一个参数的值是数字1,代表着以引用的方式传递。其实这个参数对于对象来说几乎没用,因为ZE2中所有的对象在当作函数参数的时候都是默认以引用的形式传递的。但是我们又必须把这个参数设置为数字1,除非你不想让你的扩展与PHP4兼容。在PHP4中,对象是传递的一个完整Copy,而非通过引用。 对于数组和对象参数,不要忘记最后的允许为NULL的参数。更多的信息请参考第6章最后一节的有关叙述。 通过arg info的方式来实现类型绑定的功能只对ZE2有效,也就是PHP5+。如果你想在PHP4上实现相应的功能,那需要用 zend_get_parameters()函数来接收参数,然后通过Z_TYPE_P()宏函数来检测参数的类型或者通过convert_to_type()函数进行类型转换。 ## links * 7.1 [zend_parse_parameters](<7.1.md>) * 7.3 [第七章小结](<7.3.md>)