Maison développement back-end tutoriel php Original : recherche du noyau PHP sur les propriétés et méthodes des membres telles que

Original : recherche du noyau PHP sur les propriétés et méthodes des membres telles que

Dec 22, 2016 am 09:58 AM

Cet article parlera en détail des attributs et méthodes des membres des classes PHP.
Dans l'article précédent, nous avons présenté la fonction zend_do_begin_class_declaration, qui est utilisée pour créer et initialiser un zend_class_entry
Toutes les informations du la classe est enregistrée dans Dans cette structure, comment les propriétés et les méthodes sont-elles stockées


1

2

3

classPerson{

public$name;

}

Vous vous souvenez également de la fonction zend_initialize_class_data mentionnée dans l'article précédent ? Peu importe si vous ne vous en souvenez pas. Regardons cette fonction de plus près

zend_initialize_class_data(new_class_entry, 1 TSRMLS_CC);

<.>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

ZEND_APIvoidzend_initialize_class_data(zend_class_entry *ce , zend_bool nullify_handlers TSRMLS_DC)/ * {{ { */

{

          zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? ) ;

ce->refcount = 1;

ce->constants_updated = 0;

ce->ce_fla gs = 0 ;

ash_init_ex(&ce ->default_properties, 0, NULL, zval_ptr_dtor_func, persistent_hashes, 0);

zend_hash_init_ex(&ce->properties_info, 0, NULL, (dtor_func_t) (persistent_hashes ? ternal : erty_info), persistent_hashes, 0); );

zend_hash_init_ex(&ce->function_table, 0, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);

if(ce->type == ZEND_INTERNAL_CLASS) {

#ifdef ZTS

intn = zend_hash_num_elements(CG(class_table));

if(CG(static_members) && n >= CG(last_static_member)) {

                                                                                                                                                                                                              CG(static_members) =realloc(CG(static_members), ( n 1)*sizeof(HashTable*));

CG(static_members)[n] = NULL;

}

ce ->static_members = (HashTable*) (zend_intptr_t)n;

#else

ce->static_members = NULL;

#endif

}else{

ce->static_members = &ce->default_static_members;

}

        if(nullify_handlers) {

                ce->constructor = NULL;

               ce->destructor = NULL;

                ce->clone = NULL;

                ce->__get = NULL;

               ce->__set = NULL;

                ce->__unset = NULL;

                ce- >__isset = NULL;

                ce->__call = NULL;

                ce->__callstatic = NULL;

                ce-> __tostring = NULL;

                ce->create_object = NULL;

               ce->get_iterator = NULL;

                ce->iterator_funcs.funcs = NULL ;

                ce- >interface_gets_implemented = NULL;

                ce->get_static_method = NULL;

               ce->parent = NULL;

                ce->num_interfaces = 0;

                ce-> unserialize = NULL;

                ce->serialize_func = NULL;

               ce->unserialize_func = NULL;

                 ce->builtin_functions = NULL;

        }

}

   

zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? 1 : 0;

普通用户类与内部类 分配内存的方式不同…. ^.^

注意看13-16行.zend_hash_init_ex(&ce- >constants_table, 0, NULL, zval_ptr_dtor_func, persistent_hashes, 0);

zend_hash_init_ex(&ce->function_table, 0, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);

如果你看过之前的文章,那么你Il s'agit d'un HashTable.

是的..初始化当然要zend_hash_init了.
第36-61行初始化魔术方法
不过这里只是初始化哦..好像并没有设置属性.$name属性是如何添加到属性表里的呢???



1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

   

unticked_class_declaration_statement :

                class_entry_type T_STRING extends_from

                        { zend_do_begin_class_declaration(&$1, &$2, &$3 TSRMLS_CC); antecedents _statement_list

                        '}'{ zend_do_end_class_declaration(&$1, &$2 TSRMLS_CC); }

        |       interface_entry T_STRING

                        { zend_do_begin_class_declaration(&$1, &$2, NULL TSRMLS_CC); }

                        interface_extends_list

                        '{'

                                 class_statement_list

                        '}'{ zend_do_end_class_declaration(&$1, &$2 TSRMLS_CC); }

;

class_statement:

                variable_modifiers { CG(access_type) = Z_LVAL($1.u.constant); } class_variable_declaration';'

        |       class_constant_declaration';'

        |       method_modifiers function is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$4, 1, $3.op_type, &$1 TSRMLS_CC); }'('

                        parameter_list')'method_body { zend_do_abstract_method(&$4, &$1, &$9 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }

;

class_variable_declaration:

               class_variable_declaration','T_VARIABLE                                                               e_property(&$3, NULL, CG(access_type) TSRMLS_CC); }

        |       class_variable_declaration','T_VARIABLE'='static_scalar     { zend_do_declare_property(&$3, &$5, CG(access_type) TSRMLS_CC); }

        |       T_VARIABLE                                               { zend_do_declare_property(&$1, NULL, CG(access_type) TSRMLS_CC); }

        |       T_VARIABLE'='static_scalar    { zend_do_declare_property(&$1, &$3, CG(access_type) TSRMLS_CC); antecedents Il s'agit d'un class_statement_list.. ^.^

类体里会调用 zend_do_declare_property处理.

1

2

3

4

5


6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

   

voidzend_do_declare_property(constznode *var_name,constznode *value, zend_uint access_type TSRMLS_DC)/* {{{ */

{

        zval *property;

        zend_property_info *existing _property_info;

        char*comment = NULL;

        intcomment_len = 0;

  

        if(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {

               zend_error(E_COMPILE_ERROR, "Les interfaces ne peuvent pas inclure de variables membres");

        }

  

        if(access_type & ZEND_ACC_ABSTRACT {

                zend_error (E_COMPILE_ERROR,"Les propriétés ne peuvent pas être déclarées abstraites");

        }

  

        if(access_type & ZEND_ACC_FINAL) {

                zend_error(E_ COMPILE_ERROR,"Impossible déclarer la propriété %s::$%s final, le modificateur final n'est autorisé que pour les méthodes et les classes",

                                      CG(active_class_entry)->name, var_name->u.constant.value.str. val);

        }

  

        if(zend_hash_find(&CG(active_class_entry)->properties_info, var_name->u.constant.value.str.val, var_name ->u.constant.value.str.len 1, (void**) &existing_property_info)==SUCCESS) {

                if(!(existing_property_info->flags & ZEND_ACC_IMPLICIT_PUBLIC)) {

                       zend_error(E_COMPILE_ERROR, "Impossible de redéclarer %s::$%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val);

                }

        }

        ALLOC_ZVAL(propriété);

  

        si(valeur) {

                *propriété = valeur-> u.constant ;

        }else{

                INIT_PZVAL(propriété);

                Z_TYPE_P(propriété) = IS_NULL;

        }

  

        if(CG(doc_comment)) {

                comment = CG(doc_comment);

               comment_len = CG(doc_comment_len);

                CG(doc_comment) = NULL ; > .constant.value.str .val, var_name->u.constant.value.str.len, property, access_type, comment, comment_len TSRMLS_CC);

        efree(var_name->u.constant.value.str.val);

}

   

Ligne 8-25 :
Si votre classe déclare une interface, alors l'interface ne peut pas avoir d'attributs et lancera Les interfaces ne peuvent pas inclure de variables membres
Si les attributs de la classe sont définis sur abstrait, alors elle le fera throw Les propriétés ne peuvent pas être déclarées abstraites
Si les propriétés de la classe sont définies sur final, alors elle lancera Impossible de déclarer la propriété %s::$%s final, le modificateur final n'est autorisé que pour les méthodes et les classes
Tout c'est bien, une donnée zval sera allouée.
Si l'attribut a une valeur initiale, alors les données seront affectées au zval. Sinon, INIT_PZVAL sera appelé pour initialiser le zval et le type est défini sur IS_NULL ;
Enfin, zend_declare_property_ex sera appelé Ajouter le zval à l'active_class_entry spécifié
Méthodes de la classe

1

2

3

4

5

classPerson{

publicfunctiontest(){

echo1;

}

}

Et si c'est une méthode ? Comment est-elle gérée ?
Regardez d'abord les règles

1

2

3

4

5

class_statement :

CG(access_type) = Z_LVAL($1.u.constant); } class_variable_declaration';'

| gin_function_declaration(&$2, &$4, " RMLS_CC); }

Le premier est l'attribut, puis le troisième est la méthode...

Zend_do_begin_function_declaration vous semble-t-il familier ?

Si vous avez lu le précédent article, vous devez Cela vous semble familier

Si vous ne l'avez pas lu, allez d'abord lire cet article La définition de la fonction

Je n'entrerai pas dans les détails ici.
Je vais juste parler de ce qui était. non mentionné dans cet article
Dans cette fonction Il y a un jugement en



1

2

3

4

5

6

7

8

9

10

11

if (is_method) {

if(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {

if((Z_LVAL(fn_flags_znode-&g t;u.constant) & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) :) .str.val);

                                                                                       reste de l'analyseur */

}

                                 fn_flags = Z_LVAL( fn_flags_znode->u.constant);                              ​​fn_flags = 0;

}

Si vous définissez les propriétés de la classe d'interface sur privée ou protégée, alors Type d'accès pour la méthode d'interface %s ::%s() doit être omis

sera lancé puis

if (zend_hash_add() sera appelé &CG(active_class_entry)->function_table, lcname, name_len 1, &op_array, sizeof(zend_op_array), ( void **) &CG(active_op_array)) == FAILURE) {

zend_error(E_COMPILE_ERROR, "Impossible de redéclarer %s:: %s()", CG(active_class_entry)->name, name);

}

Ajoutez la méthode directement à la function_table.

Ce qui suit fera différents jugements basés sur différentes déclarations de classe.

Ce qui précède est le contenu original : recherche du noyau PHP et autres attributs et méthodes des membres. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !


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)
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Commandes de chat et comment les utiliser
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

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)

Comment supprimer des amis WeChat ? Comment supprimer des amis WeChat Comment supprimer des amis WeChat ? Comment supprimer des amis WeChat Mar 04, 2024 am 11:10 AM

WeChat est l'un des outils de chat traditionnels. Nous pouvons rencontrer de nouveaux amis, contacter d'anciens amis et entretenir l'amitié entre amis grâce à WeChat. Tout comme il n’existe pas de banquet qui ne se termine jamais, des désaccords surviendront inévitablement lorsque les gens s’entendront bien. Lorsqu'une personne affecte extrêmement votre humeur ou que vous constatez que vos points de vue sont incohérents lorsque vous vous entendez bien et que vous ne pouvez plus communiquer, nous devrons peut-être supprimer les amis WeChat. Comment supprimer des amis WeChat ? La première étape pour supprimer des amis WeChat : appuyez sur [Carnet d'adresses] sur l'interface principale de WeChat ; la deuxième étape : cliquez sur l'ami que vous souhaitez supprimer et entrez [Détails] ; la troisième étape : cliquez sur [...] en haut. coin droit ; Étape 4 : Cliquez sur [Supprimer] ci-dessous ; Étape 5 : Après avoir compris les invites de la page, cliquez sur [Supprimer le contact] ;

Comment écrire un roman dans l'application Tomato Free Novel Partagez le tutoriel sur la façon d'écrire un roman dans l'application Tomato Novel Comment écrire un roman dans l'application Tomato Free Novel Partagez le tutoriel sur la façon d'écrire un roman dans l'application Tomato Novel Mar 28, 2024 pm 12:50 PM

Tomato Novel est un logiciel de lecture de romans très populaire. Nous avons souvent de nouveaux romans et bandes dessinées à lire dans Tomato Novel. De nombreux amis souhaitent également gagner de l'argent de poche et éditer le contenu de leur roman. Je veux écrire dans du texte. Alors, comment pouvons-nous y écrire le roman ? Mes amis ne le savent pas, alors allons ensemble sur ce site. Prenons le temps de regarder une introduction à la façon d'écrire un roman. Partagez le didacticiel du roman Tomato sur la façon d'écrire un roman. 1. Ouvrez d'abord l'application de roman gratuite Tomato sur votre téléphone mobile et cliquez sur Personal Center - Writer Center 2. Accédez à la page Tomato Writer Assistant - cliquez sur Créer un nouveau livre. à la fin du roman.

Comment entrer dans le bios sur la carte mère Colorful ? Apprenez-vous deux méthodes Comment entrer dans le bios sur la carte mère Colorful ? Apprenez-vous deux méthodes Mar 13, 2024 pm 06:01 PM

Les cartes mères colorées jouissent d'une grande popularité et d'une part de marché élevée sur le marché intérieur chinois, mais certains utilisateurs de cartes mères colorées ne savent toujours pas comment accéder au BIOS pour les paramètres ? En réponse à cette situation, l'éditeur vous a spécialement proposé deux méthodes pour accéder au bios coloré de la carte mère. Venez l'essayer ! Méthode 1 : utilisez la touche de raccourci de démarrage du disque U pour accéder directement au système d'installation du disque U. La touche de raccourci de la carte mère Colorful pour démarrer le disque U en un seul clic est ESC ou F11. Tout d'abord, utilisez Black Shark Installation Master pour créer un Black. Disque de démarrage Shark U, puis allumez l'ordinateur lorsque vous voyez l'écran de démarrage, appuyez continuellement sur la touche ESC ou F11 du clavier pour accéder à une fenêtre de sélection de la séquence d'éléments de démarrage. Déplacez le curseur à l'endroit où "USB. " s'affiche, puis

Comment récupérer des contacts supprimés sur WeChat (un tutoriel simple vous explique comment récupérer des contacts supprimés) Comment récupérer des contacts supprimés sur WeChat (un tutoriel simple vous explique comment récupérer des contacts supprimés) May 01, 2024 pm 12:01 PM

Malheureusement, les gens suppriment souvent certains contacts accidentellement pour certaines raisons. WeChat est un logiciel social largement utilisé. Pour aider les utilisateurs à résoudre ce problème, cet article explique comment récupérer les contacts supprimés de manière simple. 1. Comprendre le mécanisme de suppression des contacts WeChat. Cela nous offre la possibilité de récupérer les contacts supprimés. Le mécanisme de suppression des contacts dans WeChat les supprime du carnet d'adresses, mais ne les supprime pas complètement. 2. Utilisez la fonction intégrée « Récupération du carnet de contacts » de WeChat. WeChat fournit une « Récupération du carnet de contacts » pour économiser du temps et de l'énergie. Les utilisateurs peuvent récupérer rapidement les contacts précédemment supprimés grâce à cette fonction. 3. Accédez à la page des paramètres WeChat et cliquez sur le coin inférieur droit, ouvrez l'application WeChat « Moi » et cliquez sur l'icône des paramètres dans le coin supérieur droit pour accéder à la page des paramètres.

Comment définir la taille de la police sur le téléphone mobile (ajustez facilement la taille de la police sur le téléphone mobile) Comment définir la taille de la police sur le téléphone mobile (ajustez facilement la taille de la police sur le téléphone mobile) May 07, 2024 pm 03:34 PM

La définition de la taille de la police est devenue une exigence de personnalisation importante à mesure que les téléphones mobiles deviennent un outil important dans la vie quotidienne des gens. Afin de répondre aux besoins des différents utilisateurs, cet article présentera comment améliorer l'expérience d'utilisation du téléphone mobile et ajuster la taille de la police du téléphone mobile grâce à des opérations simples. Pourquoi avez-vous besoin d'ajuster la taille de la police de votre téléphone mobile - L'ajustement de la taille de la police peut rendre le texte plus clair et plus facile à lire - Adapté aux besoins de lecture des utilisateurs d'âges différents - Pratique pour les utilisateurs malvoyants qui souhaitent utiliser la taille de la police fonction de configuration du système de téléphonie mobile - Comment accéder à l'interface des paramètres du système - Dans Rechercher et entrez l'option "Affichage" dans l'interface des paramètres - recherchez l'option "Taille de la police" et ajustez-la. application - téléchargez et installez une application prenant en charge l'ajustement de la taille de la police - ouvrez l'application et entrez dans l'interface des paramètres appropriée - en fonction de l'individu

Résumé des méthodes pour obtenir les droits d'administrateur dans Win11 Résumé des méthodes pour obtenir les droits d'administrateur dans Win11 Mar 09, 2024 am 08:45 AM

Un résumé de la façon d'obtenir les droits d'administrateur Win11 Dans le système d'exploitation Windows 11, les droits d'administrateur sont l'une des autorisations très importantes qui permettent aux utilisateurs d'effectuer diverses opérations sur le système. Parfois, nous pouvons avoir besoin d'obtenir des droits d'administrateur pour effectuer certaines opérations, telles que l'installation de logiciels, la modification des paramètres du système, etc. Ce qui suit résume quelques méthodes pour obtenir les droits d'administrateur Win11, j'espère que cela pourra vous aider. 1. Utilisez les touches de raccourci. Dans le système Windows 11, vous pouvez ouvrir rapidement l'invite de commande via les touches de raccourci.

Le secret de l'éclosion des œufs de dragon mobiles est révélé (étape par étape pour vous apprendre à réussir l'éclosion des œufs de dragon mobiles) Le secret de l'éclosion des œufs de dragon mobiles est révélé (étape par étape pour vous apprendre à réussir l'éclosion des œufs de dragon mobiles) May 04, 2024 pm 06:01 PM

Les jeux mobiles font désormais partie intégrante de la vie des gens avec le développement de la technologie. Il a attiré l'attention de nombreux joueurs avec sa jolie image d'œuf de dragon et son processus d'éclosion intéressant, et l'un des jeux qui a beaucoup attiré l'attention est la version mobile de Dragon Egg. Pour aider les joueurs à mieux cultiver et faire grandir leurs propres dragons dans le jeu, cet article vous présentera comment faire éclore des œufs de dragon dans la version mobile. 1. Choisissez le type d'œuf de dragon approprié. Les joueurs doivent choisir soigneusement le type d'œuf de dragon qu'ils aiment et qui leur conviennent, en fonction des différents types d'attributs et de capacités d'œuf de dragon fournis dans le jeu. 2. Améliorez le niveau de la machine d'incubation. Les joueurs doivent améliorer le niveau de la machine d'incubation en accomplissant des tâches et en collectant des accessoires. Le niveau de la machine d'incubation détermine la vitesse d'éclosion et le taux de réussite de l'éclosion. 3. Collectez les ressources nécessaires à l'éclosion. Les joueurs doivent être dans le jeu.

Explication détaillée de la méthode de requête de version Oracle Explication détaillée de la méthode de requête de version Oracle Mar 07, 2024 pm 09:21 PM

Explication détaillée de la méthode de requête de version Oracle Oracle est l'un des systèmes de gestion de bases de données relationnelles les plus populaires au monde. Il offre des fonctions riches et des performances puissantes et est largement utilisé dans les entreprises. Dans le processus de gestion et de développement de bases de données, il est très important de comprendre la version de la base de données Oracle. Cet article présentera en détail comment interroger les informations de version de la base de données Oracle et donnera des exemples de code spécifiques. Interrogez la version de base de données de l'instruction SQL dans la base de données Oracle en exécutant une simple instruction SQL

See all articles