Maison  >  Article  >  développement back-end  >  Introduction détaillée au principe du chargement automatique de php

Introduction détaillée au principe du chargement automatique de php

王林
王林original
2019-09-02 16:55:075421parcourir

Introduction détaillée au principe du chargement automatique de php

En parlant du chargement automatique de PHP, de nombreux étudiants peuvent penser aux fonctions de chargement automatique de divers frameworks, aux principes PSR0 et PSR4 dans la spécification PHP, à la fonction de chargement automatique de Composer, etc. Tous offrent une grande commodité pour notre développement.

Alors quelles sont les causes et les conséquences du chargement automatique de PHP ? Quels sont les principes internes de PHP ? Ensuite, j'analyserai et résumerai en fonction de ma propre compréhension :

Pourquoi y a-t-il un chargement automatique ?

En programmation PHP orientée objet (OO), afin de faciliter la gestion, on va écrire une classe dans un fichier séparé, puis si on veut l'utiliser en classe A La fonction de classe B nécessite de charger la classe B dans la classe A. À l'origine, nous avons implémenté ces exigences via la syntaxe require et include. Les résultats de ces deux syntaxes sont fondamentalement les mêmes. Il existe certaines différences dans le processus d'exécution, qui ne seront pas expliquées ici. Par exemple :

//文件 B.php
<?php
class B{
    public function echo_info(){
        echo "我是class B中的方法执行结果";
    }
}
?>
//文件 A.php
<?php
require &#39;b.php&#39;;//include &#39;b.php&#39;;
class A{
    public function test(){
        $b_object = new B();
        $b_object->echo_info();
    }
}
$a_object = new A();
$a_oject->test();
?>
命令行输入:#php a.php
    输出: “我是class B中的方法执行结果“

Par conséquent, PHP5 implémente la fonction de chargement automatique (Autoload) des classes. Cette fonction a été à l'origine implémentée via une méthode magique __autoload() en PHP. Plus tard, l'extension PHP SPL (Standard PHP Library) a implémenté un mécanisme de chargement automatique plus puissant.

Chargement automatique d'origine php

Tout d'abord, introduisons la méthode __autoload(). Toujours en utilisant l'exemple de tout à l'heure, vous pouvez utiliser __autoload() pour apporter les modifications suivantes :

//文件 B.php 不做修改
//文件 A.php
<?php
class A{
    public function test(){
        $b_object = new B();
        $b_object->echo_info();
    }
}
function __autoload($classname){
    require $classname.&#39;.php&#39;;//include &#39;b.php&#39;;
}
$a_object = new A();
$a_oject->test();
?>
命令行输入:#php a.php
    输出: “我是class B中的方法执行结果“

Nous avons ajouté une fonction au fichier A : __autoload(), et avons écrit la méthode d'introduction correspondante dans la fonction après l'exécution. Le même résultat a été obtenu, aucune erreur n’a été signalée. Nous devons préciser que la fonction __autoload() PHP s'exécutera automatiquement lorsqu'elle ne trouvera pas la classe. Cependant, cette fonction n'est pas définie en interne dans PHP. Cette fonction doit être définie par le développeur lui-même et la logique interne écrite. PHP est uniquement responsable de son exécution automatique en cas de besoin. Et lors de l'appel, le nom de la classe à charger sera automatiquement passé en paramètre.

Avec la fonction __autoload(), on voit que si nous devons introduire 100 autres fichiers maintenant, il nous suffit de définir une règle et d'écrire une fonction. C'est une grande amélioration par rapport à l'utilisation directe de require/inlude, mais il y a aussi de nouveaux problèmes dans un projet, nous ne pouvons écrire qu'une seule fonction __autoload(). Si le projet est relativement volumineux, les mêmes règles seront utilisées pour charger chaque fichier. . Évidemment, ce n'est pas réaliste, nous devrons alors peut-être écrire une logique de règles complexe dans __autoload() pour répondre aux besoins de chargement de différents fichiers. Cela rendra également la fonction __autoload() complexe et gonflée, ce qui la rendra difficile à maintenir et à gérer.

En conséquence, le mécanisme de chargement automatique de SPL (Standard PHP Library Standard PHP Library) a vu le jour.

Chargement automatique SPL

Tout d'abord, soyons clairs, lorsque PHP instancie un objet (implémente en fait interface, en utilisant des constantes de classe ou des variables statiques dans la classe, ce sera le cas lors de l'appel de méthodes statiques dans la classe), il vérifiera d'abord si la classe (ou l'interface) existe dans le système, et si elle n'existe pas, elle va essayer d'utiliser le mécanisme de chargement automatique pour charger le genre de classe. Le processus d'exécution principal du mécanisme de chargement automatique est :

1 Vérifiez si le pointeur de fonction de variable globale de l'exécuteur autoload_func est NULL ; > 2. Si autoload_func==NULL, vérifiez si le système définit la fonction __autoload() Si elle est définie, exécutez-la et renvoyez le résultat du chargement. S'il n'est pas défini, une erreur sera signalée et quittera

3. Si autoload_func n'est pas égal à NULL, la fonction pointée par autoload_func sera exécutée directement pour charger la classe. ne vérifiera pas si la fonction __autoload() est définie.

En comprenant le processus de chargement automatique de PHP, vous pouvez voir que PHP fournit en fait deux méthodes pour implémenter le mécanisme de chargement automatique :

L'une que nous avons mentionnée précédemment consiste à utiliser l'utilisateur. Le __autoload défini ( ) la fonction est généralement implémentée dans le programme source PHP ;

L'autre consiste à concevoir une fonction et à pointer le pointeur autoload_func vers elle, qui est généralement implémentée dans l'extension PHP en utilisant le langage C, c'est-à-dire le mécanisme de chargement automatique SPL.

Si les deux méthodes sont implémentées, c'est-à-dire que autoload_func n'est pas égal à NULL, le programme n'exécutera que la deuxième méthode et la fonction __autoload() ne sera pas exécutée.

Regardons d'abord un exemple de chargement automatique SPL :

B.php文件不变
A.php
<?php
class A{
    public function test(){
        $b_object = new B();
        $b_object->echo_info();
    }
}

function __autoload($classname){
    require $classname.&#39;.php&#39;;//include &#39;b.php&#39;;
}

function my_autoload($classname){
    require $classname.&#39;.php&#39;;//include &#39;b.php&#39;;
    echo &#39;my_autoload   &#39;;
}

spl_autoload_register(&#39;my_autoload&#39;);
$a_object = new A();
$a_object->test();

结果:my_autoload  我是class B中的方法执行结果
?>

Dans ce petit exemple, vous pouvez voir que grâce à spl_autoload_register ("my_autoload"), lorsque l'exécution du programme ne trouve pas la classe B, le La fonction my_autoload() personnalisée sera exécutée pour charger la classe B. En fait, la fonction de spl_autoload_register('my_autoload') est de pointer le pointeur autoload_func vers my_autoload(). Désormais, l’ensemble du processus de chargement automatique de PHP devient clair.

Analyse détaillée du processus de chargement automatique SPLTout d'abord, prenons le petit exemple de tout à l'heure If spl_autoload_register ('my_autoload'. ) est remplacé par spl_autoload_register() La classe B peut-elle être chargée sans ajouter de paramètres ? La réponse est : OUI.

Pourquoi ?

因为SPL扩展内部自己定义了一个自动加载函数 spl_autoload(),实现了自动加载的功能,如果我们不定义自己的自动加载函数,并且程序里写了 spl_autoload_register()(如果不传参数,必须是第一次执行才会有效)或者 spl_autoload_register(’spl_autoload’),那么autoload_func 指针就会指向内部函数 spl_autoload()。程序执行的时候如果找不到相应类就会执行该自动加载函数。

那么,SPL 是怎么实现autoload_func 指针指向不同的函数呢?

原来,在SPL内部定义了 一个函数 spl_autoload_call() 和 一个全局变量autoload_functions。autoload_functions本质上是一个HashTable,不过我们可以将其简单的看作一个链表,链表中的每一个元素都是一个函数指针,指向一个具有自动加载类功能的函数。

spl_autoload_call()的作用就是按顺序遍历 autoload_functions,使得autoload_func指向每个自动加载函数,如果加载成功就停止,如果不成功就继续遍历下个自动加载函数,直到加载成功或者遍历完所有的函数。

那么,autoload_functions 这个列表是谁来维护的呢?就是 spl_autoload_register() 这个函数。我们说的自动加载函数的注册,其实就是通过spl_autoload_register()把自动加载函数加入到 autoload_functions 列表。

到此为止,整个自动加载的流程就是分析结束了。

  相关SPL自动加载函数:
  spl_autoload_functions() //打印autoload_functions列表
  spl_autoload_unregister() //注销自动加载函数

以上便是php自动加载原理的全部介绍,想了解更多相关内容请访问PHP中文网:PHP视频教程

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