淺談PHP源碼二十八:關於類結構和繼承

來源:互聯網
上載者:User
這篇文章主要介紹了關於淺談PHP源碼二十八:關於類結構和繼承,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

淺談PHP源碼二十八:關於類結構和繼承

作為物件導向中一個非常關鍵也非常糾結的特性,我們需要瞭解一些
在PHP5中,從一開始就有了繼承的概念,今天我們從PHP源碼出發,瞭解他是怎麼實現的。
在瞭解類的繼承之前,我們需要知道類在PHP源碼中是以哪種方式儲存的。
找到zend/zend.h 418行:

 struct _zend_class_entry {char type;char *name;/* 類名 */zend_uint name_length;/* 類名字串長度 */struct _zend_class_entry *parent; /* 父類 */int refcount; /* 引用計數 */zend_bool constants_updated;zend_uint ce_flags;/* 類的存取控制 */ HashTable function_table;/*類的成員函數 */HashTable default_properties;/*類的預設屬性 */HashTable properties_info;/*類的屬性資訊 如存取控制等 */HashTable default_static_members;/*靜態成員列表 */HashTable *static_members;HashTable constants_table;/* 常量列表 */const struct _zend_function_entry *builtin_functions; union _zend_function *constructor;/*建構函式*/union _zend_function *destructor;/*解構函式*/union _zend_function *clone;/*複製方法*/ /*魔術方法 */union _zend_function *__get;union _zend_function *__set;union _zend_function *__unset;union _zend_function *__isset;union _zend_function *__call;union _zend_function *__callstatic;union _zend_function *__tostring;union _zend_function *serialize_func;union _zend_function *unserialize_func; zend_class_iterator_funcs iterator_funcs; /* handlers */zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC);zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* a class implements this interface */union _zend_function *(*get_static_method)(zend_class_entry *ce, char* method, int method_len TSRMLS_DC); /* serializer callbacks */int (*serialize)(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC);int (*unserialize)(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC); zend_class_entry **interfaces;/*類實現的介面 */zend_uint num_interfaces;/*類實現的介面數 */ /*類所在檔案資訊 */char *filename;zend_uint line_start;zend_uint line_end;char *doc_comment;zend_uint doc_comment_len; struct _zend_module_entry *module;};

從PHP內建的SPL中,我們可以看到有類的繼承,從這裡出發,可以找到我們所需要的實現過程

從手冊中選擇CachingIterator類作為切入點。
CachingIterator extends IteratorIterator implements OuterIterator , Traversable , Iterator , ArrayAccess , Countable
跟蹤過程如下:

 //在ext/spl/spl_iterators.c 3246行,REGISTER_SPL_SUB_CLASS_EX(CachingIterator, IteratorIterator, spl_dual_it_new, spl_funcs_CachingIterator); //    ext/spl/spl_functions.h 34行#define REGISTER_SPL_SUB_CLASS_EX(class_name, parent_class_name, obj_ctor, funcs) \    spl_register_sub_class(&spl_ce_ ## class_name, spl_ce_ ## parent_class_name, # class_name, obj_ctor, funcs TSRMLS_CC); //    ext/spl/spl_functions.c 56行PHPAPI void spl_register_sub_class(zend_class_entry ** ppce, zend_class_entry * parent_ce, char * class_name, void *obj_ctor, const zend_function_entry * function_list TSRMLS_DC)*ppce = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC); //    zend/zend_API.c  2196行ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce, char *parent_name TSRMLS_DC)zend_do_inheritance(register_class, parent_ce TSRMLS_CC); //    zend/zend_compile.c 2784行 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);    }     /* final類不能繼承 */    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;    /* 拷貝序列化和還原序列化回呼函數 */    if (!ce->serialize) {    ce->serialize   = parent_ce->serialize;    }    if (!ce->unserialize) {    ce->unserialize = parent_ce->unserialize;    }     /* 繼承父類的介面 在此處有停下來思考,為何要這麼做 */    zend_do_inherit_interfaces(ce, parent_ce TSRMLS_CC);     /* 繼承父類的屬性  */    zend_hash_merge(&ce->default_properties, &parent_ce->default_properties, (void (*)(void *)) zval_add_ref, NULL, sizeof(zval *), 0);    if (parent_ce->type != ce->type) {    /* 使用者自訂的類從內部類繼承 */    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, (void (*)(void *)) zval_add_ref, 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);    }}

關於上面do_inherit_parent_constructor(ce)

此方法實現魔術方法繼承,如果子類中沒有相關的魔術方法,則繼承父類的對應方法。如下所示的PHP代碼為子類沒建構函式的情況

class Base {public function __construct() {    echo 'Base __construct<br />';}} class Foo extends Base { } $foo = new Foo();

如上,會輸出:Base __construct
顯然繼承了父類的構造方法,如果子類有自己的構造方法,並且需要調用父類的構造方法時,需要在子類的構造方法中調用父類的構造方法,PHP不會自動調用。

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.