在定义一个类时往往会使其继承某个父类或者实现某个接口,在扩展中实现这个功能非常方便。下面我先给出PHP语言中的代码。
02 | interface i_myinterface |
04 | public function hello(); |
07 | class parent_class implements i_myinterface |
09 | public function hello() |
11 | echo "Good Morning!\n" ; |
15 | final class myclass extends parent_class |
17 | public function call_hello() |
上面的代码我们已经非常熟悉了,它们在PHP扩展中的实现应该是这样的:
02 | zend_class_entry *i_myinterface_ce,*parent_class_ce,*myclass_ce; |
05 | ZEND_METHOD(parent_class,hello) |
07 | php_printf( "hello world!\n" ); |
11 | ZEND_METHOD(myclass,call_hello) |
15 | this_zval = getThis(); |
16 | zend_call_method_with_0_params(&this_zval,myclass_ce,NULL, "hello" ,NULL); |
20 | static zend_function_entry i_myinterface_method[]={ |
21 | ZEND_ABSTRACT_ME(i_myinterface, hello, NULL) |
25 | static zend_function_entry parent_class_method[]={ |
26 | ZEND_ME(parent_class,hello,NULL,ZEND_ACC_PUBLIC) |
30 | static zend_function_entry myclass_method[]={ |
31 | ZEND_ME(myclass,call_hello,NULL,ZEND_ACC_PUBLIC) |
35 | ZEND_MINIT_FUNCTION(test) |
37 | zend_class_entry ce,p_ce,i_ce; |
38 | INIT_CLASS_ENTRY(i_ce, "i_myinterface" ,i_myinterface_method); |
39 | i_myinterface_ce = zend_register_internal_interface(&i_ce TSRMLS_CC); |
43 | INIT_CLASS_ENTRY(p_ce, "parent_class" ,parent_class_method); |
44 | parent_class_ce = zend_register_internal_class(&p_ce TSRMLS_CC); |
45 | zend_class_implements(parent_class_ce TSRMLS_CC,1,i_myinterface_ce); |
48 | INIT_CLASS_ENTRY(ce, "myclass" ,myclass_method); |
49 | myclass_ce = zend_register_internal_class_ex(&ce,parent_class_ce, "parent_class" TSRMLS_CC); |
51 | myclass_ce->ce_flags |= ZEND_ACC_FINAL_CLASS; |
这样,当我们在PHP语言中进行如下操作时,便会得到预期的输出:
这里的ZEND_ABSTRACT_ME()宏函数比较特殊,它会声明一个abstract public类型的函数,这个函数不需要我们实现,因此也就不需要相应的ZEND_METHOD(i_myinterface,hello){...}的实现。一般来说,一个接口是不能设计出某个非public类型的方法的,因为接口暴露给使用者的都应该是一些公开的信息。不过如果你非要这么设计,那也不是办不到,只要别用ZEND_ABSTRACT_ME()宏函数就行了,而用它的底层实现ZEND_FN()宏函数。
2 | static zend_function_entry i_myinterface[]= |
4 | ZEND_FENTRY(apply_request, NULL, NULL, ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_PUBLIC) |
这样,只要掩码中有ZEND_ACC_ABSTRACT,便代表是一个不需要具体实现的方法。ZEND_FENTRY其实是ZEND_ME和ZEND_FE的最终实现,现在我们把这一组宏罗列在这一次展开,供你参考使用。
1 | #define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags }, |
3 | #define ZEND_FN(name) zif_##name |
5 | #define ZEND_MN(name) zim_##name |
7 | #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0) |
9 | #define ZEND_ME(classname, name, arg_info, flags) ZEND_FENTRY(name, ZEND_MN(classname##_##name), arg_info, flags) |
没有帐号? 现在注册.