Maison  >  Article  >  développement back-end  >  Principes, classes et objets sous-jacents PHP

Principes, classes et objets sous-jacents PHP

步履不停
步履不停original
2019-06-19 10:32:222528parcourir

Principes, classes et objets sous-jacents PHP

Pour PHPer, la POO est une pensée de développement indispensable, mais comment Que savez-vous de l'implémentation sous-jacente des classes et des objets PHP ? Basé sur l'idée de​​savoir ce qui se passe et pourquoi, trouvons la réponse ensemble~

L'implémentation sous-jacente d'une classe peut être considérée comme un ensemble de connaissances de variables, de fonctions , etc. dont nous avons déjà parlé. Par conséquent, les étudiants qui souhaitent comprendre plus en profondeur devraient consulter mes articles précédents sur l'introduction de variables et de fonctions

Structure des données de classe

Qu'il s'agisse d'une classe ordinaire, d'une classe abstraite ou d'une interface, stockée dans un structure unifiée, et lors de la génération de code intermédiaire, cette classe sera ajoutée à la liste globale des classes. Bien sûr, à ce moment-là, le nom de la classe sera utilisé pour déterminer si la classe existe déjà. Si elle existe, l'ajout échouera

struct _zend_class_entry {
    char type;     // 和函数一样,类被拆分为两种类型:ZEND_INTERNAL_CLASS 内部类型和ZEND_USER_CLASS 用户自定义类型
    char *name;// 类名称
    zend_uint name_length;                  // 即sizeof(name) - 1
    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; // type == ZEND_USER_CLASS时,取&default_static_members;
    // type == ZEND_INTERAL_CLASS时,设为NULL
    HashTable constants_table;     // 常量存放集合
    struct _zend_function_entry *builtin_functions;// 方法定义入口
 
	/* 魔术方法 */
    //所有魔术方法单独存放,初始化时被设置为null
    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 *__tostring;
    union _zend_function *serialize_func;
    union _zend_function *unserialize_func;
    zend_class_iterator_funcs iterator_funcs;// 迭代
 
    /* 类句柄 */
    zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC);
    zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object,
        intby_ref TSRMLS_DC);
 
    /* 类声明的接口 */
    int(*interface_gets_implemented)(zend_class_entry *iface,
            zend_class_entry *class_type TSRMLS_DC);
 
 
    /* 序列化回调函数指针 */
    int(*serialize)(zval *object, unsignedchar**buffer, zend_uint *buf_len,
             zend_serialize_data *data TSRMLS_DC);
    int(*unserialize)(zval **object, zend_class_entry *ce, constunsignedchar*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; // 类所在的模块入口:EG(current_module)
};

Comme le montre le code ci-dessus, les variables membres et le membre. les méthodes de la classe sont stockées dans leurs Dans la structure respective, la structure des données de la structure est exactement la même que la structure des données des variables et des fonctions expliquée précédemment, sauf que les variables membres compilées et les méthodes membres sont stockées dans la structure de la classe

Génération d'objets

Nous savons tous que les objets sont créés par de nouveaux, mais d'un point de vue de bas niveau, la génération d'objets est divisée en trois étapes
La première étape : déterminer si la classe existe dans la liste globale des classes en fonction du nom de la classe. Si S'il existe, récupérez la variable de la classe de stockage
Étape 2 : Déterminez si la classe est une classe normale (classe non abstraite ou interface si c'est le cas) ; une classe normale, allouez de la mémoire au conteneur zval où l'objet doit être créé et définissez le type de conteneur Pour IS_OBJECT
Étape 3 : Effectuez l'opération d'initialisation de l'objet et ajoutez l'objet à la liste globale d'objets (pool d'objets)

Attachez la structure de données de l'objet :

typedef struct _zend_object {
    zend_class_entry *ce; //对象的类结构
    HashTable *properties; //对象属性
    HashTable *guards; /* protects from __get/__set ... recursion */
} zend_object;

Obtenez et définissez la variable des membres

Obtenez les variables des membres :
La première étape consiste à obtenir les propriétés de l'objet. Recherchez s'il existe. est un attribut correspondant au nom issu des propriétés de l'objet. S'il existe, retournez le résultat. S'il n'existe pas, passez à la deuxième étape
La deuxième étape, si la méthode get magic existe, appelez cette méthode. pour obtenir la variable. Si elle n'existe pas, une erreur sera signalée.

Définissez les variables membres :
La première étape, récupérez les propriétés de l'objet, à partir des propriétés de l'objet, détermine s'il existe un propriété correspondant au nom. Si elle existe et que la valeur existante est la même que la valeur à définir, aucune opération n'est effectuée. Sinon, l'opération d'affectation de variable est effectuée. Si elle n'existe pas, passez à la deuxième étape.
Étape 2, si la méthode magique _set existe, appelez cette méthode pour définir la variable. Si elle n'existe pas, passez à la troisième étape
La troisième étape, si la variable membre n'a jamais été définie, ajoutez directement cette variable au champ propriétés de l'objet Situé dans HashTable.

Résumé

Jusqu'à présent, nous avons presque parlé des principes sous-jacents de PHP. Bien sûr, pendant cette période, de nombreux étudiants m'ont dit qu'ils avaient progressivement commencé à utiliser php7. Le contenu que vous expliquez maintenant est toujours php5. En fait, mon explication de php5 est également de préparer php7. Après tout, php7 est une extension de php5. Après avoir compris php5, il sera plus facile de comprendre php7. De plus, php n'a été amélioré que progressivement depuis php5. Nous devons comprendre le contenu de php5. Mais à partir de la semaine prochaine, nous commencerons à comparer les différences entre php7 et php5 de bas en haut, alors restez à l'écoute ~

Pour plus d'articles techniques liés à PHP, veuillez visiter Colonne Tutoriel PHP pour apprendre !

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:
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