自己寫PHP擴展之實現類的繼承
聲明:本文為斯人原創,全部為作者一一分析得之,有不對的地方望賜教。
歡迎轉載,轉載請注明出處 。
本文地址:http://imsiren.com/archives/593
如果我們想繼承某一個類,我們怎么辦?
比如 Siren類繼承Secure類.
[html] view plaincopy
</div>
- class Secure{
- public function test(){
- echo "this is Secure::test";
- }
- }
- class Siren extends Secure{
- } </ol> </div>
- 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); </ol> </div>
- 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
- }; </ol> </div>
- 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;
- }; </ol> </div>
- 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 </ol> </div> 根據名字就能看出來,這里就不做一一介紹了.
- 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);
- }
- } </ol> </div>
- 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){
- }; </ol> </div>
這樣一個類,該怎么做?
其實沒有什么大不同,跟創建一個普通類是一樣的..只是有一些稍作改動..
1.在頭文件中聲明方法
[html] view plaincopy
</div>
2.在c文件中 創建 method指針,注意 要一一對應.secure_method和 siren_method不能放在一個指針里.
[html] view plaincopy
</div>
3.在PHP_MINIT_FUNCTION中注冊兩個類 這里是重點哦
[html] view plaincopy
</div>
第2-3行 //創建對象..secure和siren
第4-5行 對兩個對象進行初始化 上一章有詳細介紹過.
第 6 行 注冊類
第 7 行 要把secure_ce聲明為一個普通類,這里一定要設置,不然 默認會是final類.這樣繼承會報錯.
除了 ZEND_ACC_IMPLICIT_PUBLIC 還有很多 類似功能的宏
[html] view plaincopy
</div>
第 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里
定義如下
[html] view plaincopy
</div>
4.添加方法體
[html] view plaincopy
</div>
這樣 Siren類就繼承了 Secure類
在php里面 執行
$a=new Siren();
$a->test();
就會輸出”this is Secure::test”
原文出處:http://imsiren.com/archives/593
本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!
推薦閱讀
自己寫PHP擴展之實現類的繼承
聲明:本文為 斯人 原創,全部為作者一一分析得之,有不對的地方望賜教。 歡迎轉載,轉載請注明出處 。 本文地址: http://imsiren.com/archives/593 如果我們想繼承某...
UML類關系: 依賴、關聯、聚合、組合、繼承、實現
1. 依賴 Class B { static void a(){...} } Class A { ??? // a. 類A的方法中使用類B作為參數 void a(B b){...} ??? //...
子類繼承父類時,子類的異常不能大于父類
在java中,當我們子類要重寫父類中的方法,如果父類的方法有異常聲明,那么子類重寫這個方法時候,所要聲明的異常不應該比父類的大。只能是小等,或者可以沒有。原因如下。 假如我們自定意義一個異常: ...