php扩展中用户自定义的方法有两大类:一类是函数(独立存在),一类是方法(依附于类和对象)。本文先说明下函数。
构造一个新的函数的原理如下:声明并实现,实现完成后在某些特定的地方写代码告诉Zend引擎(注册)。完成这两步后就可以了。
假如需要实现一个foo()的方法,可以直接在php脚本中调用: php -r "foo();"
第一步:声明和实现
声明和实现使用PHP_FUNCTION(foo){...}或者ZEND_FUNTION(foo){...},这两个宏的作用完全相同,区别在于较老版本的php扩展都是使用PHP_FUNCTION,新的扩展使用ZEND_FUNTION,换了个马甲。
在宏的{...},可以完成具体的业务逻辑,比如最简单的输入一个字符串什么的。
ZEND_FUNTION(foo){php_printf("hello foo/n");}
这样即完成了函数的声明和实现。
第二步:向Zend引擎注册该函数
在所生成的扩展源代码中有如下类似的结构:
这个结构里面即是用来给扩展注册自定义函数的地方,我们先写上注册的代码
可以看到增加了一行语句,PHP_FALIAS也是Zend提供的一个宏,PHP_FALIAS的意思是向Zend注册进去一个函数,同时声明了在php脚本中这个函数的名称。第一个参数是在普通php脚本中调用的名称,第二个参数是向Zend注册的在第一步中声明的函数名称,第三个为NULL和函数的参数传递有管,暂时不管它,置为NULL就可以了。
和上面相同,PHP_FALIAS也可以使用ZEND_FALIAS代替,换个马甲而已。
编译完成后,就可以这样调用了:
如果我们把PHP_FALIAS(foo,foo,NULL)修改为 PHP_FALIAS(foo1,foo,NULL), 则可以这样调用:
宏的含义:
PHP_FUNCTION(foo)宏展开后,得到的C代码如下:
可以发现该方法被加了前缀zif_,而且多了5个参数。这些参数都是自动添加进去的,具体含义现在不用管它,我们只关注函数名的改变。
其实,所有类似foo的扩展中自定义的方法最终编译完成后都会带上zif_的前缀, 我们通过nm检查生成的so文件也能够看出来。
而PHP_FALIAS(foo,foo,NULL)这个宏呢,会首先把第二个参数添加上zif_的前缀,然后再注册到Zend的引擎中。通过这个宏完成php脚本中的方法名和Zend引擎中真实的方法名的映射。
zif_的意义:
可以防止扩展中定义的方法和Zend本身具有的方法重名,起到了命名空间的作用。
构造一个新的函数的原理如下:声明并实现,实现完成后在某些特定的地方写代码告诉Zend引擎(注册)。完成这两步后就可以了。
假如需要实现一个foo()的方法,可以直接在php脚本中调用: php -r "foo();"
第一步:声明和实现
声明和实现使用PHP_FUNCTION(foo){...}或者ZEND_FUNTION(foo){...},这两个宏的作用完全相同,区别在于较老版本的php扩展都是使用PHP_FUNCTION,新的扩展使用ZEND_FUNTION,换了个马甲。
在宏的{...},可以完成具体的业务逻辑,比如最简单的输入一个字符串什么的。
ZEND_FUNTION(foo){php_printf("hello foo/n");}
这样即完成了函数的声明和实现。
第二步:向Zend引擎注册该函数
在所生成的扩展源代码中有如下类似的结构:
- function_entry foo_functions[] = {
- { NULL, NULL, NULL }
- };
- function_entry foo_functions[] = {
- PHP_FALIAS(foo, foo, NULL)
- { NULL, NULL, NULL }
- };
和上面相同,PHP_FALIAS也可以使用ZEND_FALIAS代替,换个马甲而已。
编译完成后,就可以这样调用了:
- <?PHP
- foo();
- ?>
- 1. <?PHP
- 2. foo1();
- 3. ?>
PHP_FUNCTION(foo)宏展开后,得到的C代码如下:
- zif_foo_echo (ht=0, return_value=0x86c3620, return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
其实,所有类似foo的扩展中自定义的方法最终编译完成后都会带上zif_的前缀, 我们通过nm检查生成的so文件也能够看出来。
而PHP_FALIAS(foo,foo,NULL)这个宏呢,会首先把第二个参数添加上zif_的前缀,然后再注册到Zend的引擎中。通过这个宏完成php脚本中的方法名和Zend引擎中真实的方法名的映射。
zif_的意义:
可以防止扩展中定义的方法和Zend本身具有的方法重名,起到了命名空间的作用。