如果我们想继承某一个类,我们怎么办?
比如 Siren类继承Secure类.
1
2
3
4
5
6
7
8
|
classSecure{
publicfunctiontest(){
echo"this is Secure::test";
}
}
classSirenextendsSecure{
}
|
这样一个类,该怎么做?
其实没有什么大不同,跟创建一个普通类是一样的..只是有一些稍作改动..
1.在头文件中声明方法
1
2
3
4
5
6
7
|
zend_class_entry *secure_ce;
zend_class_entry *siren_ce;
PHP_METHOD(Secure,__construct);
PHP_METHOD(Secure,__destruct);
PHP_METHOD(Secure,test);
PHP_METHOD(Siren,__construct);
PHP_METHOD(Siren,__destruct);
|
2.在c文件中 创建 method指针,注意 要一一对应.secure_method和 siren_method不能放在一个指针里.
1
2
3
4
5
6
7
8
9
10
11
|
constzend_function_entry secure_methods[]={
PHP_ME(Secure,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(Secure,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
PHP_ME(Secure,test,NULL,ZEND_ACC_PUBLIC)
PHP_FE_END
};
constzend_function_entry siren_methods[]={
PHP_ME(Siren,__construct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(Siren,__destruct,NULL,ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
PHP_FE_END
};
|
3.在PHP_MINIT_FUNCTION中注册两个类 这里是重点哦
1
2
3
4
5
6
7
8
9
10
|
PHP_MINIT_FUNCTION(secure){
zend_class_entry secure;
zend_class_entry siren;
INIT_CLASS_ENTRY(secure,"Secure",secure_methods);//初始化
INIT_CLASS_ENTRY(siren,"Siren",siren_methods);//初始化 上一章都详细介绍过
secure_ce=zend_register_internal_class_ex(&secure,NULL,NULL TSRMLS_DC);
secure_ce->ce_flags=ZEND_ACC_IMPLICIT_PUBLIC;
siren_ce=zend_register_internal_class_ex(&siren,secure_ce,NULL TSRMLS_DC);
returnSUCCESS;
};
|
第2-3行 //创建对象..secure和siren
第4-5行 对两个对象进行初始化 上一章有详细介绍过.
第 6 行 注册类
第 7 行 要把secure_ce声明为一个普通类,这里一定要设置,不然 默认会是final类.这样继承会报错.
除了 ZEND_ACC_IMPLICIT_PUBLIC 还有很多 类似功能的宏
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
ZEND_ACC_ABSTRACT
ZEND_ACC_ALLOW_STATIC
ZEND_ACC_CALL_VIA_HANDLER
ZEND_ACC_CHANGED
ZEND_ACC_CLONE
ZEND_ACC_CLOSURE
ZEND_ACC_CTOR
ZEND_ACC_DEPRECATED
ZEND_ACC_DTOR
ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
ZEND_ACC_FINAL
ZEND_ACC_FINAL_CLASS
ZEND_ACC_IMPLEMENTED_ABSTRACT
ZEND_ACC_IMPLEMENT_INTERFACES
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS
ZEND_ACC_IMPLICIT_PUBLIC
ZEND_ACC_INTERACTIVE
ZEND_ACC_INTERFACE
ZEND_ACC_PPP_MASK
ZEND_ACC_PRIVATE
ZEND_ACC_PROTECTED
ZEND_ACC_PUBLIC
ZEND_ACC_SHADOW
ZEND_ACC_STATIC
|
根据名字就能看出来,这里就不做一一介绍了.
第 8 行 把siren注册到我们的Hash表里面.注意zend_register_internal_class_ex的第二个参数
zend_register_internal_class_ex(`
第二个参数就是 父类的指针.
该函数会调用 zend_do_inheritance 将parent_ce的 属性 类 复制到 class_entry里
定义如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
ZEND_APIvoidzend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC)/* {{{ */
{
if((ce->ce_flags & ZEND_ACC_INTERFACE)
&& !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
zend_error(E_COMPILE_ERROR,"Interface %s may not inherit from class (%s)", ce->name, parent_ce->name);
}
if(parent_ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
zend_error(E_COMPILE_ERROR,"Class %s may not inherit from final class (%s)", ce->name, parent_ce->name);
}
ce->parent = parent_ce;
/* Copy serialize/unserialize callbacks */
if(!ce->serialize) {
ce->serialize = parent_ce->serialize;
}
if(!ce->unserialize) {
ce->unserialize = parent_ce->unserialize;
}
/* Inherit interfaces */
zend_do_inherit_interfaces(ce, parent_ce TSRMLS_CC);
/* Inherit properties */
zend_hash_merge(&ce->default_properties, &parent_ce->default_properties, zval_property_ctor(parent_ce, ce), NULL,sizeof(zval *), 0);
if(parent_ce->type != ce->type) {
/* User class extends internal class */
zend_update_class_constants(parent_ce TSRMLS_CC);
zend_hash_apply_with_arguments(CE_STATIC_MEMBERS(parent_ce) TSRMLS_CC, (apply_func_args_t)inherit_static_prop, 1, &ce->default_static_members);
}else{
zend_hash_apply_with_arguments(&parent_ce->default_static_members TSRMLS_CC, (apply_func_args_t)inherit_static_prop, 1, &ce->default_static_members);
}
zend_hash_merge_ex(&ce->properties_info, &parent_ce->properties_info, (copy_ctor_func_t) (ce->type & ZEND_INTERNAL_CLASS ? zend_duplicate_property_info_internal : zend_duplicate_property_info),sizeof(zend_property_info), (merge_checker_func_t) do_inherit_property_access_check, ce);
zend_hash_merge(&ce->constants_table, &parent_ce->constants_table, zval_property_ctor(parent_ce, ce), NULL,sizeof(zval *), 0);
zend_hash_merge_ex(&ce->function_table, &parent_ce->function_table, (copy_ctor_func_t) do_inherit_method,sizeof(zend_function), (merge_checker_func_t) do_inherit_method_check, ce);
do_inherit_parent_constructor(ce);
if(ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS && ce->type == ZEND_INTERNAL_CLASS) {
ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
}elseif(!(ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES)) {
/* The verification will be done in runtime by ZEND_VERIFY_ABSTRACT_CLASS */
zend_verify_abstract_class(ce TSRMLS_CC);
}
}
|
4.添加方法体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
PHP_METHOD(Secure,__construct){
php_printf("construct is running");
};
PHP_METHOD(Secure,__destruct){
};
PHP_METHOD(Secure,test){
php_printf("this is Secure::test");
};
PHP_METHOD(Siren,__construct){
};
PHP_METHOD(Siren,__destruct){
};
|
这样 Siren类就继承了 Secure类
在php里面 执行
$a=new Siren();
$a->test();
就会输出”this is Secure::test”