這篇文章主要介紹了關於淺談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)
class Base { public function __construct() { echo 'Base __construct<br />'; }} class Foo extends Base { } $foo = new Foo();
關於上面do_inherit_parent_constructor(ce)
rrreee關於上面do_inherit_parent_constructor(ce)
rrreee
#如果先得到處理。子類別中沒有相關的魔術方法,則繼承父類別的對應方法。如下所示的PHP程式碼為子類別沒建構子的情況
如上,會輸出:Base __construct顯然繼承了父類別的建構方法,如果子類別有自己的建構方法,並且當需要呼叫父類別的建構方法時,需要在子類別的建構方法中呼叫父類別的建構方法,PHP不會自動呼叫。
以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!
以上是淺談PHP源碼二十八:關於類別結構與繼承的詳細內容。更多資訊請關注PHP中文網其他相關文章!

負載均衡會影響會話管理,但可以通過會話複製、會話粘性和集中式會話存儲解決。 1.會話複製在服務器間複製會話數據。 2.會話粘性將用戶請求定向到同一服務器。 3.集中式會話存儲使用獨立服務器如Redis存儲會話數據,確保數據共享。

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

PHP會話的替代方案包括Cookies、Token-basedAuthentication、Database-basedSessions和Redis/Memcached。 1.Cookies通過在客戶端存儲數據來管理會話,簡單但安全性低。 2.Token-basedAuthentication使用令牌驗證用戶,安全性高但需額外邏輯。 3.Database-basedSessions將數據存儲在數據庫中,擴展性好但可能影響性能。 4.Redis/Memcached使用分佈式緩存提高性能和擴展性,但需額外配

Sessionhijacking是指攻擊者通過獲取用戶的sessionID來冒充用戶。防範方法包括:1)使用HTTPS加密通信;2)驗證sessionID的來源;3)使用安全的sessionID生成算法;4)定期更新sessionID。

本文比較了PHP和ASP.NET,重點是它們對大規模Web應用程序,性能差異和安全功能的適用性。兩者對於大型項目都是可行的,但是PHP是開源和無關的,而ASP.NET,


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

Atom編輯器mac版下載
最受歡迎的的開源編輯器

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具