>  기사  >  백엔드 개발  >  PHP 자동 로딩 원리에 대한 자세한 소개

PHP 자동 로딩 원리에 대한 자세한 소개

王林
王林원래의
2019-09-02 16:55:075411검색

PHP 자동 로딩 원리에 대한 자세한 소개

PHP의 자동 로딩에 대해 말하면 많은 학생들이 다양한 프레임워크의 자동 로딩 기능, PHP 사양의 PSR0 및 PSR4 원칙, Composer의 자동 로딩 기능 등을 생각할 수 있습니다. 이러한 모든 것은 우리 개발에 많은 것을 제공합니다. . 매우 편리합니다.

그렇다면 PHP 자동 로딩의 원인과 결과는 무엇일까요? PHP의 내부 원칙은 무엇입니까? 다음으로 제가 이해한 내용을 바탕으로 분석 및 요약을 해보겠습니다.

자동 로딩이 왜 있나요?

PHP 객체 지향(OO) 프로그래밍에서는 관리를 용이하게 하기 위해 별도의 파일에 클래스를 작성하므로 클래스 A에서 클래스 B의 기능을 사용하려면 다음을 넣어야 합니다. 클래스 B 클래스 A에 로드합니다. 원래는 require 및 include 구문을 통해 이러한 요구 사항을 구현했습니다. 이 두 구문의 결과는 기본적으로 실행 프로세스에 몇 가지 차이점이 있으므로 여기서는 설명하지 않습니다. 예:

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

그래서 PHP5는 클래스의 자동 로딩(Autoload) 기능을 구현합니다. 이 기능은 원래 PHP의 매직 메소드 __autoload()를 통해 구현되었습니다. 나중에 PHP 확장 SPL(표준 PHP 라이브러리)은 더욱 강력한 자동 로딩 메커니즘을 구현했습니다.

php 원본 자동 로딩

먼저 __autoload() 메소드를 소개하겠습니다. 지금의 예제를 계속 사용하면 __autoload()를 사용하여 다음과 같이 수정할 수 있습니다.

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

파일 A: __autoload()에 함수를 추가하고 함수에 해당 소개 메서드를 작성했습니다. 동일한 결과가 보고되었으며 오류가 보고되지 않았습니다. __autoload() 함수는 PHP가 클래스를 찾을 수 없을 때 자동으로 실행된다는 점을 분명히 해야 합니다. 그러나 이 함수는 PHP에서 내부적으로 정의되지 않으며 개발자가 직접 정의해야 하며 내부 로직을 작성해야 합니다. PHP는 필요할 때만 자동 실행을 담당합니다. 그리고 호출 시 로드할 클래스 이름이 자동으로 매개변수로 전달됩니다.

__autoload() 함수를 사용하면 지금 100개의 다른 파일을 도입해야 한다면 규칙을 설정하고 함수를 작성하기만 하면 된다는 것을 알 수 있습니다. 이는 require/inlude를 직접 사용하는 것보다 크게 개선되었지만 프로젝트에서는 __autoload() 함수를 하나만 작성할 수 있으므로 각 파일을 로드하는 데 동일한 규칙이 사용됩니다. 분명히 비현실적이므로, 다른 파일을 로드해야 하는 요구 사항을 충족하려면 __autoload()에 복잡한 규칙 논리를 작성해야 할 수도 있습니다. 이는 또한 __autoload() 함수를 복잡하고 비대하게 만들어 유지 관리를 어렵게 만듭니다.

그래서 SPL(Standard PHP Library Standard PHP Library)의 자동 로딩 메커니즘이 탄생했습니다.

SPL 자동 로딩

우선, PHP는 객체를 인스턴스화할 때 이 작업을 수행합니다(실제로 인터페이스를 구현할 때, 클래스에서 클래스 상수 또는 정적 변수를 사용하고 정적 메서드를 호출할 때). in a class) 그래서) 먼저 시스템에 클래스(또는 인터페이스)가 존재하는지 확인하고, 존재하지 않으면 자동 로드 메커니즘을 사용하여 클래스를 로드하려고 시도합니다. 자동 로드 메커니즘의 주요 실행 프로세스는 다음과 같습니다.

1 실행기 전역 변수 함수 포인터 autoload_func가 NULL인지 확인합니다.

2 autoload_func==NULL인 경우 시스템이 __autoload()를 정의하는지 확인합니다. function 은 정의된 경우 로드 결과를 실행하고 반환합니다. 정의되지 않은 경우 오류가 보고되고 종료됩니다.

3. autoload_func가 NULL이 아닌 경우 autoload_func가 가리키는 함수가 직접 실행되어 클래스를 로드하는지 여부를 확인하지 않습니다. __autoload() 함수가 정의되었습니다.

PHP 자동 로딩 프로세스를 이해하면 PHP가 실제로 자동 로딩 메커니즘을 구현하는 두 가지 방법을 제공한다는 것을 알 수 있습니다.

우리가 이전에 언급한 것 중 하나는 사용자 정의 __autoload() 함수를 사용하는 것입니다. 이는 일반적으로 다음에서 구현됩니다.

다른 방법은 함수를 설계하고 autoload_func 포인터를 가리키는 것입니다. 이는 일반적으로 C 언어, 즉 SPL 자동 로드 메커니즘을 사용하여 PHP 확장에서 구현됩니다.

두 메서드가 모두 구현되면, 즉 autoload_func가 NULL이 아닌 경우 프로그램은 두 번째 메서드만 실행하고 __autoload() 함수는 실행되지 않습니다.

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

이 작은 예제에서는 spl_autoload_register('my_autoload')를 통해 프로그램이 클래스 B를 찾을 수 없을 때 사용자 정의된 my_autoload() 함수가 실행되는 것을 볼 수 있습니다. , 클래스 B를 로드합니다. 실제로 spl_autoload_register('my_autoload')의 함수는 autoload_func 포인터를 my_autoload()로 가리키는 것입니다. 이제 전체 PHP 자동 로딩 프로세스가 명확해졌습니다.

SPL 자동 로딩 프로세스에 대한 자세한 분석먼저 작은 예를 들어보겠습니다. 매개 변수를 추가하지 않고 spl_autoload_register('my_autoload')를 spl_autoload_register()로 변경하면 클래스 B가 짐을 실은? 대답은: 그렇습니다.

왜?

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

위 내용은 PHP 자동 로딩 원리에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.