自己寫PHP擴充之實作類別的繼承

來源:互聯網
上載者:User
聲明:本文為斯人原創,全部為作者一一分析得之,有不對的地方望賜教。
歡迎轉載,轉載請註明出處 。
本文地址: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_ABSTRACTZEND_ACC_ALLOW_STATICZEND_ACC_CALL_VIA_HANDLERZEND_ACC_CHANGEDZEND_ACC_CLONEZEND_ACC_CLOSUREZEND_ACC_CTORZEND_ACC_DEPRECATEDZEND_ACC_DTORZEND_ACC_EXPLICIT_ABSTRACT_CLASSZEND_ACC_FINALZEND_ACC_FINAL_CLASSZEND_ACC_IMPLEMENTED_ABSTRACTZEND_ACC_IMPLEMENT_INTERFACESZEND_ACC_IMPLICIT_ABSTRACT_CLASSZEND_ACC_IMPLICIT_PUBLICZEND_ACC_INTERACTIVEZEND_ACC_INTERFACEZEND_ACC_PPP_MASKZEND_ACC_PRIVATEZEND_ACC_PROTECTEDZEND_ACC_PUBLICZEND_ACC_SHADOWZEND_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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.