php 类继承自动加载,自己写PHP扩展之实现类的继承

声明:本文为

斯人原创,全部为作者一一分析得之,有不对的地方望赐教。

欢迎转载,转载请注明出处 。

本文地址:

http://imsiren.com/archives/593

如果我们想继承某一个类,我们怎么办?

比如 Siren类继承Secure类.

class Secure{

public function test(){

echo "this is Secure::test";

}

}

class Siren extends Secure{

}

这样一个类,该怎么做?

其实没有什么大不同,跟创建一个普通类是一样的..只是有一些稍作改动..

1.在头文件中声明方法

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不能放在一个指针里.

const zend_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

};

const zend_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中注册两个类 这里是重点哦

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);

return SUCCESS;

};

第2-3行 //创建对象..secure和siren

第4-5行 对两个对象进行初始化 上一章有详细介绍过.

第 6 行 注册类

第 7 行 要把secure_ce声明为一个普通类,这里一定要设置,不然 默认会是final类.这样继承会报错.

除了 ZEND_ACC_IMPLICIT_PUBLIC 还有很多 类似功能的宏

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_class_entry *parent_ce>`,`< char *parent_name TSRMLS_DC>`)

第二个参数就是 父类的指针.

该函数会调用 zend_do_inheritance 将parent_ce的 属性 类 复制到 class_entry里

定义如下

ZEND_API void zend_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;

} else if (!(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.添加方法体

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”

原文出处:

http://imsiren.com/archives/593

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值