PHPの自動読み込み原理の詳細な紹介

王林
リリース: 2023-02-23 14:40:02
オリジナル
5424 人が閲覧しました

PHPの自動読み込み原理の詳細な紹介

PHP の自動ローディングといえば、さまざまなフレームワークの自動ローディング機能、PHP 仕様の PSR0 および PSR4 の原則、Composer の自動ローディング機能などを思い浮かべる学生も多いかもしれません。これらはすべて開発に非常に便利です。

それでは、PHP の自動読み込みの原因と結果は何でしょうか? PHP の内部原則は何ですか?次に、私自身の理解に基づいて分析してまとめます。

なぜ自動ロードがあるのか​​?

PHP オブジェクト指向 (OO) プログラミングでは、管理を容易にするために、クラスを別のファイルに記述し、クラス内で使用する場合に使用します。 A クラス B の関数では、クラス B をクラス A にロードする必要があります。当初は、このような要件を require 構文と include 構文で実装していましたが、これら 2 つの構文の結果は基本的に同じですが、実行プロセスにいくつかの違いがあるため、ここでは説明しません。例:

//文件 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 (Standard PHP Library) により、より強力な自動ロード メカニズムが実装されました。

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() に関数を追加し、関数内に対応する導入メソッドを記述しました。同じ結果が得られ、エラーは報告されませんでした。 PHP の __autoload() 関数は、クラスが見つからない場合に自動的に実行されることを明確にする必要があります。ただし、この関数は PHP の内部で定義されていません。この関数は開発者自身が定義し、内部ロジックを記述する必要があります。 PHP は、必要なときに関数を自動的に実行することのみを担当します。実行を呼び出します。そして呼び出し時には、ロードされるクラスの名前がパラメータとして自動的に渡されます。

__autoload() 関数を使用すると、他の 100 個のファイルを導入する必要がある場合、ルールを設定して関数を記述するだけで済むことがわかります。これは、require/inlude を直接使用する場合に比べて大幅な改善ですが、新しい問題もあります。プロジェクトでは、__autoload() 関数を 1 つしか作成できません。プロジェクトが比較的大きい場合は、同じルールが各ファイルのロードに使用されます。明らかに非現実的なので、さまざまなファイルをロードするニーズを満たすために __autoload() に複雑なルール ロジックを記述する必要があるかもしれません。また、これにより __autoload() 関数が複雑かつ肥大化し、保守と管理が困難になります。

そこで、SPL (Standard PHP Library Standard PHP Library) の自動ロード機構が登場しました。

SPL 自動読み込み

まず、PHP がオブジェクト (実際にインターフェイスを実装する) をインスタンス化するときは、次のことを明確にします。 、クラス内でクラス定数または静的変数を使用する場合、これはクラス内で静的メソッドを呼び出す場合に当てはまります)、最初にクラス (またはインターフェイス) がシステム内に存在するかどうかを確認し、存在しない場合は、自動ロード メカニズムを使用してクラスをロードしてみます。オートロード メカニズムの主な実行プロセスは次のとおりです:

1. 実行プログラムのグローバル変数関数ポインター autoload_func が NULL かどうかを確認します;

2. autoload_func==NULL の場合、システムに __autoload() 関数が定義されているかどうかを確認し、定義されている場合はそれを実行し、ロード結果を返します。定義されていない場合、エラーが報告されて終了します;

3. autoload_func が NULL に等しくない場合、autoload_func が指す関数が直接実行され、クラスがロードされます。 __autoload() 関数が定義されているかどうかはチェックされません。

PHP の自動読み込みプロセスを理解すると、PHP が実際に自動読み込みメカニズムを実装するための 2 つのメソッドを提供していることがわかります。

前に述べた 1 つは、ユーザーが定義したメソッドを使用することです。 __autoload() 関数は通常、PHP ソース プログラムに実装されます。

もう 1 つは関数を設計し、autoload_func ポインタをその関数に指す方法で、通常は C 言語を使用して PHP 拡張機能、つまり SPL オートロードに実装されます。機構。

両方のメソッドが実装されている場合、つまり autoload_func が NULL に等しくない場合、プログラムは 2 番目のメソッドのみを実行し、__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中的方法执行结果
?>
ログイン後にコピー

この小さな例では、プログラムの実行でクラス B が見つからない場合に、spl_autoload_register ('my_autoload') を通じて、カスタマイズされた 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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート