Maison développement back-end tutoriel php Une brève discussion sur le code source PHP vingt-huit : à propos de la structure des classes et de l'héritage

Une brève discussion sur le code source PHP vingt-huit : à propos de la structure des classes et de l'héritage

Jun 29, 2018 am 09:24 AM

Cet article présente principalement une brève discussion sur le code source PHP 28 : concernant la structure des classes et l'héritage, il a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer

Un bref. discussion Code source PHP vingt-huit : À propos de la structure des classes et de l'héritage

En tant que fonctionnalité très critique et très complexe de l'orientation objet, nous devons comprendre quelque chose
En PHP5, le concept d'héritage est là Depuis le début, nous partons aujourd'hui du code source PHP pour comprendre comment il est implémenté.
Avant de comprendre l'héritage des classes, nous devons savoir comment les classes sont stockées dans le code source PHP.
Trouvez la ligne 418 de zend/zend.h :

 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;};
Copier après la connexion

À partir du SPL fourni avec PHP, nous pouvons voir l'héritage des classes. De là, nous pouvons trouver le processus d'implémentation dont nous avons besoin <. 🎜>

Sélectionnez la classe CachingIterator dans le manuel comme point d'entrée.

CachingIterator étend IteratorIterator implémente OuterIterator, Traversable, Iterator, ArrayAccess, Countable
Le processus de suivi est le suivant :

 //在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);
    }}
Copier après la connexion
À propos de ce qui précède do_inherit_parent_constructor(ce)

Cette méthode implémente l'héritage de la méthode magique , s'il n'y a pas de méthode magique pertinente dans la sous-classe, la méthode correspondante de la classe parent est héritée. Le code PHP ci-dessous est le cas où la sous-classe n'a pas de constructeur

class Base {
public function __construct() {
    echo &#39;Base __construct<br />&#39;;
}} class Foo extends Base { } $foo = new Foo();
Copier après la connexion
comme ci-dessus, il affichera : Base __construct

hérite évidemment du constructeur de la classe parent, si la sous-classe a le sien constructor , et lorsque vous devez appeler le constructeur de la classe parent, vous devez appeler le constructeur de la classe parent dans le constructeur de la sous-classe, et PHP ne l'appellera pas automatiquement.

Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !

Recommandations associées :

Une brève discussion du code source PHP vingt-sept : identification par PHP des méthodes de construction

A brève discussion sur le code source PHP vingt-six : Simplification de l'implémentation du code source de tri rapide PHP

Une brève discussion sur le code source PHP vingt-cinq : à propos de la clé suivante, actuelle fonctions

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Où trouver la courte de la grue à atomide atomique
1 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Travailler avec les données de session Flash dans Laravel Travailler avec les données de session Flash dans Laravel Mar 12, 2025 pm 05:08 PM

Laravel simplifie la gestion des données de session temporaires à l'aide de ses méthodes de flash intuitives. Ceci est parfait pour afficher de brefs messages, alertes ou notifications dans votre application. Les données ne persistent que pour la demande ultérieure par défaut: $ demande-

PHP Logging: meilleures pratiques pour l&amp;#39;analyse du journal PHP PHP Logging: meilleures pratiques pour l&amp;#39;analyse du journal PHP Mar 10, 2025 pm 02:32 PM

La journalisation PHP est essentielle pour surveiller et déboguer les applications Web, ainsi que pour capturer des événements critiques, des erreurs et un comportement d&amp;#39;exécution. Il fournit des informations précieuses sur les performances du système, aide à identifier les problèmes et prend en charge le dépannage plus rapide

Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST Mar 14, 2025 am 11:42 AM

L'extension PHP Client URL (CURL) est un outil puissant pour les développeurs, permettant une interaction transparente avec des serveurs distants et des API REST. En tirant parti de Libcurl, une bibliothèque de transfert de fichiers multi-protocol très respectée, PHP Curl facilite Efficient Execu

Misque de réponse HTTP simplifié dans les tests Laravel Misque de réponse HTTP simplifié dans les tests Laravel Mar 12, 2025 pm 05:09 PM

Laravel fournit une syntaxe de simulation de réponse HTTP concise, simplifiant les tests d'interaction HTTP. Cette approche réduit considérablement la redondance du code tout en rendant votre simulation de test plus intuitive. L'implémentation de base fournit une variété de raccourcis de type de réponse: Utiliser illuminate \ support \ faades \ http; Http :: faux ([[ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

12 meilleurs scripts de chat PHP sur Codecanyon 12 meilleurs scripts de chat PHP sur Codecanyon Mar 13, 2025 pm 12:08 PM

Voulez-vous fournir des solutions instantanées en temps réel aux problèmes les plus pressants de vos clients? Le chat en direct vous permet d'avoir des conversations en temps réel avec les clients et de résoudre leurs problèmes instantanément. Il vous permet de fournir un service plus rapide à votre personnalité

Expliquez le concept de liaison statique tardive en PHP. Expliquez le concept de liaison statique tardive en PHP. Mar 21, 2025 pm 01:33 PM

L'article traite de la liaison statique tardive (LSB) dans PHP, introduite dans PHP 5.3, permettant une résolution d'exécution de la méthode statique nécessite un héritage plus flexible. Problème main: LSB vs polymorphisme traditionnel; Applications pratiques de LSB et perfo potentiel

Frameworks de personnalisation / d'extension: comment ajouter des fonctionnalités personnalisées. Frameworks de personnalisation / d'extension: comment ajouter des fonctionnalités personnalisées. Mar 28, 2025 pm 05:12 PM

L'article examine l'ajout de fonctionnalités personnalisées aux cadres, en se concentrant sur la compréhension de l'architecture, l'identification des points d'extension et les meilleures pratiques pour l'intégration et le débogage.

See all articles