Home  >  Article  >  Backend Development  >  Detailed introduction to the principle of php automatic loading

Detailed introduction to the principle of php automatic loading

王林
王林Original
2019-09-02 16:55:075423browse

Detailed introduction to the principle of php automatic loading

Speaking of PHP's automatic loading, many students may think of the automatic loading functions of various frameworks, the PSR0 and PSR4 principles in the PHP specification, the automatic loading function of Composer, etc. All provide great convenience for our development.

So what are the causes and consequences of PHP automatic loading? What are the internal principles of PHP? Next, I will analyze and summarize based on my own understanding:

Why is there automatic loading?

In PHP object-oriented (OO) programming, in order to facilitate management, we will write a class in a separate file, then if we want to use it in class A The function of class B requires loading class B into class A. In the original time, we implemented such requirements through require and include syntax. The results of these two syntaxes are basically the same. There are some differences in the execution process, which will not be explained here. For example:

//文件 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中的方法执行结果“

So, PHP5 implements the automatic loading (Autoload) function of the class. This function was originally implemented through a magic method __autoload() in PHP. Later, the PHP extension SPL (Standard PHP Library) implemented a more powerful automatic loading mechanism.

php original automatic loading

First, let’s introduce the __autoload() method. Still using the example just now, you can use __autoload() to make the following modifications:

//文件 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中的方法执行结果“

We added a function to file A: __autoload(), and wrote the corresponding introduction method in the function. After running The same result was obtained, no error was reported. We need to make it clear that the __autoload() function PHP will automatically execute when it cannot find the class. However, this function is not defined internally in PHP. This function needs to be defined by the developer himself and the internal logic written. PHP is only responsible for automatically executing the function when needed. Call execution. And when calling, the name of the class to be loaded will be automatically passed as a parameter.

With the __autoload() function, it can be seen that if we need to introduce 100 other files now, we only need to set a rule and write a function. This is a great improvement over using require/inlude directly, but there are also new problems. In a project, we can only write one __autoload() function. If the project is relatively large, the same rules will be used to load each file. Obviously it is unrealistic, then we may need to write complex rule logic in __autoload() to meet the needs of loading different files. This will also make the __autoload() function complex and bloated, making it difficult to maintain and manage.

So, the automatic loading mechanism of SPL (Standard PHP Library Standard PHP Library) came into being.

SPL automatic loading

First of all, make it clear that when PHP instantiates an object (actually implementing Interface, using class constants or static variables in the class, this will be the case when calling static methods in the class), first it will check whether the class (or interface) exists in the system, and if it does not exist, it will try to use the autoload mechanism to load the class. kind. The main execution process of the autoload mechanism is:

1. Check whether the executor global variable function pointer autoload_func is NULL;

2. If autoload_func==NULL, check whether the system defines the __autoload() function. If it is defined, execute it and return the loading result. If it is not defined, an error will be reported and exit;

3. If autoload_func is not equal to NULL, the function pointed to by autoload_func will be executed directly to load the class. At this time, it will not check whether the __autoload() function is defined.

Through the understanding of the PHP automatic loading process, we can see that PHP actually provides two methods to implement the automatic loading mechanism:

One we have mentioned before is to use the user The defined __autoload() function is usually implemented in the PHP source program;

The other is to design a function and point the autoload_func pointer to it, which is usually implemented in the PHP extension using C language, that is SPL autoload mechanism.

If both methods are implemented, that is, autoload_func is not equal to NULL, the program will only execute the second method, and the __autoload() function will not be executed.

Let’s first look at an SPL automatic loading example:

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中的方法执行结果
?>

In this small example, you can see that through spl_autoload_register ('my_autoload'), when the program execution cannot find class B, The customized my_autoload() function will be executed to load class B. In fact, the function of spl_autoload_register('my_autoload') is to point the autoload_func pointer to my_autoload(). Now, the entire PHP autoloading process becomes clear.

Detailed analysis of the SPL automatic loading process

First of all, let’s take the small example just now. If you change spl_autoload_register('my_autoload') to spl_autoload_register() Can class B be loaded without adding any parameters? The answer is: YES.

why?

因为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视频教程

The above is the detailed content of Detailed introduction to the principle of php automatic loading. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn