Explication détaillée du noyau PHP des classes et du code orienté objet

黄舟
Libérer: 2023-03-06 13:18:02
original
1336 Les gens l'ont consulté

Quand je suis entré en contact avec PHP pour la première fois, j'ai utilisé une approche orientée processus pour créer des sites Web très simples pour le plaisir, et j'ai simplement écrit PHP L'empilement, l'évolutivité et la maintenabilité sont si médiocres qu'il est extrêmement gênant de changer la logique. Plus tard, j'ai découvert que PHP supportait l'orientation objet, et du coup j'ai senti que j'étais vraiment jeune et ignorant à cette époque. Après tout, PHP est implémenté en C, ce qui n'est pas surprenant.

Avant-propos :

De notre contact PHPAu départ, la première chose que nous rencontrons, ce sont les fonctions : fonctions d'opération sur tableau, fonctions d'opération sur chaîne, fonctions d'opération sur fichier, etc. Ces fonctions sont la base de notre utilisation de PHP, et elles constituent également la programmation orientée processus que PHP prend en charge depuis sa naissance. Orienté processus, il encapsule les fonctions une par une et résout les problèmes avec une idée modulaire.

La programmation orientée objet est supportée depuis PHP4. Cependant, le support orienté objet de PHP4 n'est pas parfait. À partir de PHP5, PHP a introduit un nouveau modèle objet (Object Model) et ajouté de nombreuses nouvelles fonctionnalités, notamment le contrôle d'accès, les classes abstraites et finales, les méthodes de classe, les méthodes magiques, les interfaces, le clonage d'objets et les astuces de type, etc. Et dans la version PHP5.3 récemment publiée, les espaces de noms, la liaison statique retardée et supplémentaires. Il existe deux méthodes magiques __callStatic() et __invoquer().

Alors, comment est-il implémenté au bas de PHP et quelle est sa structure ?

Un. Structure de classe

Un exemple de citation de TIPI :

class ParentClass {
}
 
interface Ifce {
        public function iMethod();
}
 
final class Tipi extends ParentClass implements Ifce {
        public static $sa = 'aaa';
        const CA = 'bbb';
 
        public function __constrct() {
        }
 
        public function iMethod() {
        }
 
        private function _access() {
        }
 
        public static function access() {
        }
}
Copier après la connexion


Une classe parent ParentClass, une interface Ifce et une sous-classe Tipi sont définies ici. La sous-classe hérite de la classe parent ParentClass, implémente l'interface Ifce et possède une variable statique $sa, une constante de classe CA, une méthode publique, une méthode privée et une méthode statique publique. Comment ces structures sont-elles implémentées dans le moteur Zend ? Comment les méthodes de classe et les variables membres sont-elles stockées ? Contrôle d'accès, comment les membres statiques sont-ils marqués ?

Tout d'abord, regardons la structure de stockage interne de la classe :


En prenant quelques champs de la structure ci-dessus, nous analysons les performances du code PHP au début de l'article dans le noyau. Comme indiqué ci-dessous  :

Nom du champDescription du champClasse ParentClassInterface IfceClasse Tipi
nomNom de la classeParentClassIfceTipi
typecatégorie2 (défini par l'utilisateur)2 (défini par l'utilisateur)2 (défini par l'utilisateur, 1 est le système construit- en classe)
parentClasse ParentVideVideClasse Parent
refcountNombre de références112
ce_flagsType de classe0144524352
function_tableListe des fonctions Videfunction_name=iMethod | type=2 | fn_flags=258function_name=__construct | 2 | fn_flags=65800
nom_fonction=_access type=2 |function_name=access | type=2 | fn_flags=257
interfacesListe des interfacesnullnullLe numéro d'interface de l'interface Ifce est 1
nom de fichierAdresse du fichier de stockage/tipi.php/tipi.php /ipi.php
line_startNombre de lignes de départ de classe1518 22
line_endNombre de lignes de fin de classe162038


二。变量与成员变量

PHP内核的存储机制(分离/改变)所介绍,

变量要么是定义在全局范围中,叫做全局变量,要么是定义在某个函数中, 叫做局部变量。

成员变量是定义在类里面,并和成员方法处于同一层次。如下一个简单的PHP代码示例,定义了一个类, 并且这个类有一个成员变量。

class Tipi { 
	public $var;
}
Copier après la connexion

1.成员变量的访问:

访问这个成员变量当然是通过对象来访问。

2.成员变量的规则:

1.接口中不允许使用成员变量

2.成员变量不能拥有抽象属性

3.不能声明成员变量为final

4.不能重复声明属性

在声明类的时候初始化了类的成员变量所在的HashTable,之后如果有新的成员变量声明时,在编译时zend_do_declare_property。函数首先检查成员变量不允许的这4 条情况。

比如:.

class Tipi { 
	public final $var;
}
Copier après la connexion

运行程序将报错,违反了第三条:Fatal error: Cannot declare property Tipi::$var final, the final modifier is allowed only for methods and classes in .. 这个错误由zend_do_declare_property函数抛出


三。函数与成员方法

成员方法从本质上来讲也是一种函数,所以其存储结构也和常规函数一样,存储在zend_function结构体中。



对于一个类的多个成员方法,它是以HashTable的数据结构存储了多个zend_function结构体。 和前面的成员变量一样,在类声明时成员方法也通过调用zend_initialize_class_data方法,初始化了整个方法列表所在的HashTable。 在类中我们如果要定义一个成员方法,格式如下:

class Tipi{ 
     public function t() {echo 1; }
}
Copier après la connexion


除去访问控制关键字,一个成员方法和常规函数是一样的,从语法解析中调用的函数一样(都是zend_do_begin_function_declaration函数), 但是其调用的参数有一些不同,第三个参数is_method,成员方法的赋值为1,表示它作为成员方法的属性。 在这个函数中会有一系统的编译判断,比如在接口中不能声明私有的成员方法。 看这样一段代码:

interface Ifce { 
    private function method();
}
Copier après la connexion


S'il est exécuté directement, le programme signalera une erreur : Erreur fatale : Type d'accès pour la méthode d'interface Ifce::method() doit être omis dans Ce code correspond au code dans la zend_do_begin_function_declaration fonction.

Quatre. Similitudes et différences entre les méthodes (Fonction) et les fonctions (Méthode)


L'implémentation des fonctions a été introduite plus tôt. méthodes consiste à comparer De même, une série de logiques est mise dans une collection pour exécution, mais il existe de nombreuses différences dans l'utilisation des deux. Nous discutons ici de la mise en œuvre des deux. Du point de vue de l'implémentation, le code interne des deux est finalement interprété comme op_array, et il n'y a aucune différence dans son exécution (sauf si des modifications spécifiques à l'objet ou des méthodes telles que $this/self sont utilisées), et la différence entre les deux se reflète dans les deux Aspects :


1 C'est la mise en œuvre de la définition (enregistrement) ; 🎜>


2. C'est la mise en œuvre de l'appel

Implémentation de la méthode de définition (enregistrement) Les fonctions et méthodes sont enregistrées dans la variable compiler_globals pendant la phase de compilation, et toutes deux utilisent les mêmes fonctions de traitement du noyau zend_do_begin_function_declaration() et zend_do_end_function_declaration() pour terminer ce processus. Le contenu interne des deux sera finalement interprété et stocké sous forme d'un tableau op_codes, mais l'emplacement "monté" après compilation est différent, comme indiqué ci-dessous :


Localisation d'enregistrement des fonctions et méthodes en PHP


Implémentation de l'appel méthode


La différence dans l'emplacement et la nature de la définition détermine que les méthodes sont plus avancées que les fonctions Plus travail de vérification, les appels de méthode ont un OPCODE supplémentaire nommé ZEND_INIT_METHOD_CALL ,

La fonction consiste à enregistrer la méthode dans execute_data.fbc, puis vous pouvez utiliser la même fonction de traitement

ZEND_DO_FCALL_BY_NAME pour le traitement.


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!

Étiquettes associées:
source: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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!