ホームページ  >  記事  >  バックエンド開発  >  PHP クラスを自動的にロードする 3 つの方法の詳細な例

PHP クラスを自動的にロードする 3 つの方法の詳細な例

伊谢尔伦
伊谢尔伦オリジナル
2017-07-01 10:26:492302ブラウズ

最近、私はコンポーザーを勉強していて、PHPに触れて以来、PHPでクラスを自動ロードする3つの方法に出会ったことに気づきました。これには、PHP独自のクラスの自動ロード方法と、PHPのサードパーティの依存関係管理ツールであるコンポーザーが含まれます。 . PHP の Yaf フレームワークでのロード方法と自動ロード方法。このブログでは主に PHP5 に付属するロード方法について詳しく紹介します。composer と Yaf の下でのクラスの自動ロードについては、次回から 2 回に分けて学習していきます。 1. 手動ロード方法

C や C++ などの言語では、PHP の別のファイルで関連するクラスやメソッドを使用する必要がある場合、include、

include_once

、require または require_once を使用してインクルードできます。プロジェクト内で使用されるファイル。このうち、4つの違いは以下の通りです。

    include はファイルに適用されます。ファイルが存在しない場合は、スキップして実行を続行するよう求めるプロンプトが表示されます。ただし、適用されるのは 1 回だけです。ファイルが存在しない場合、実行は続行されます。
  • require はファイルを適用することを意味します。ファイルが存在しない場合は、
  • require_once もファイルに適用されます。
  • 上記の 4 つの方法は、ファイルが必要なときに手動でプログラムにファイルを組み込むことです。プロジェクトのサイズが比較的小さい場合は問題ありませんが、プロジェクトのサイズが大きくなると、各ファイルに必要なクラスを手動でロードするのは悪夢のような作業になります。
  • トラブルを避けるために、ロード時に

    set_include_path

    ()を通じてロードパスを設定できます。また、
  • get_include_path
()を通じてロードパスを取得することもできます。 set_include_path() と get_include_path() については、まだ触れたばかりなので、ここでは set_include_path() について簡単に説明するだけにし、今後問題が発生したときに追加します。

まず、set_include_path()はスクリプト内のphp.iniのinclude_pathを動的に変更するものですが、このinclude_pathはincludeとrequireをするものです(以下特に説明がない場合、includeはincludeとinclude_onceを表し、requireはrequireのパスを表します) require_once) を設定するか、事前定義します。 main.php ファイルの projname/home/lib/mylib/test フォルダーで a.php、b.php、c.php... を使用する必要がある場合、含まれるパスが設定されていない場合は、それを次のように記述します。次の形式:

<?php

        include("projname/home/lib/mylib/test/a.php");
        include("projname/home/lib/mylib/test/b.php");
        include("projname/home/lib/mylib/test/c.php");
	  ......
このように、各インクルードには絶対パスを含める必要があり、非常に面倒に思えます。インクルードする必要のあるファイルの前に set_include_path("projname/home/lib/mylib/test") を追加すると、次の形式で記述できます:
<?php

    set_include_path("projname/home/lib/mylib/test");
    include("a.php");
    include("b.php");
    include("c.php");
    ......
最初の時間と労力のかかる記述方法と比較、 2 番目 2 番目の方法では、明らかに時間を大幅に節約できますが、各ファイルをインクルードする必要があり、インクルードされるパスが簡素化されるだけです。もちろん、上記の状況では、必要なファイルがすべて 1 つのフォルダーに存在する場合、ファイルがインクルードされている場合は、set_include_path() ステートメントを複数追加できます。 name が複数のディレクトリに存在する場合、 set_include_path ディレクトリに最初に存在するファイルのみが含まれます。 set_include_path で指定されたすべてのフォルダーに対応するファイルがなく、そのファイル名がたまたま現在のフォルダーに存在する場合は、そのファイルに直接含まれます。現在のディレクトリ内の対応するファイル。

get_include_path() 関数は、現在のインクルード パスを取得する場合にのみ適しています。

2._autoloadとspl_autoload_register()の自動ロードメソッド

クラスロードメソッドから手を解放するために、PHP5以降のバージョンでは自動ロード機構---autoloadが提供されています。オートロードを使用すると、最初からすべてのクラス ファイルを含めたり要求したりするのではなく、実際に必要な場合にのみクラスをロードできます。これは遅延ロードと呼ばれます。 PHP が提供する自動ロード機構は、autoload() と spl_autoload_register() の 2 つのタイプに分かれています。

1).オートロード機構

PHP5でプログラムを実行する過程で、特定のクラスが含まれていないことが判明した場合、autoload自動ロード機構が実行され、必要なクラスがロードされます。これは次のように書かれています:

<?php

	public function  autoload($classname) {
		$fileName = $classname."php";
		if (file_exist($fileName)) {
			require_once("$fileName");
		} else {
			echo $fileName." doesn&#39;t exist!"
		}
	}

このプログラムの書き方に基づいて、次の結論を導き出すことができます:

自動読み込みメカニズムを保証する原則は、クラス名とファイル名に対応関係を持たせることです。名前 + サフィックスは、このクラスの名前を構成します。ファイルが存在する場合、クラスは $fileName に基づいてロードされます。ファイルが存在しない場合は、ファイルが存在しないことを示すプロンプトがユーザーに表示されます。一般に、自動読み込みメカニズムには 3 つのステップが含まれます:

クラス名に基づいてファイル名を決定します。つまり、クラス名とファイル名の統一された対応規則を決定します。

  • ファイル名に従って、ディスク上の対応するファイルを見つけます (例は最も単純なケースです。つまり、クラスとそれらを呼び出す PHP ファイルが同じディレクトリにない場合です)。 、 set_include_path () を使用できます。ロードするパスを指定します。

  • ディスク ファイルをファイル システムにロードします。この手順は、一般的なインクルードを使用するだけであり、対応するクラス ファイルをインクルードする必要があります。 () はクラスの自動ロードの原理を実装します。つまり、クラス名とファイル名の間には統一された対応関係があり、これがシステムに自動ロードを実装するための鍵となります。ただし、システムは異なる担当者によって開発される可能性があり、開発前に統一された標準が合意されていない場合、対応するルールが異なる可能性があり、そのため autoload() で複数の読み込みルールを実装する必要が生じ、autoload( が発生する可能性があります)。 ) 関数が非常に肥大化します。この問題を解決するために、PHPでは自動ロード機構---spl_autoload_register().

  • 2) 機構も提供しています

    SPLとはStandard PHP Library (Standard PHP Library)の略で、で紹介されています。 PHP5の拡張ライブラリです。 SPL オートロードは、関数ポインター autoload_func を autoload 関数にポイントすることによって実装されます。 SPL には、spl_autoload と spl_autoload_call という 2 つの異なる自動ロード関数があり、これら 2 つの異なるロード関数のアドレスを autoload_fun に指定することで、異なる自動ロード メカニズムを実装できます。

    spl_autoload

    • spl_autoload は、SPL によって実装されるデフォルトの自動ロード関数です。 2 つのパラメーターを受け取ることができる関数です。最初の関数は $class_name で、ロードされるクラスの名前を表します。2 番目のパラメーターは $file_extension で、オプションのパラメーターであり、クラス ファイルの拡張子を表します。 $file_extension には複数の拡張子を指定できます。拡張子はセミコロンで区切って指定できます。拡張子が指定されていない場合は、デフォルトの拡張子 .inc または .php が使用されます。 spl_autoload は、まず $class_name を小文字に変更し、次にすべての include_path で $class_name.inc または $class_name.php ファイルを検索します。対応するファイルが見つかった場合は、対応するクラスがロードされます。実際、spl_autoload("xxxx", ".php") を手動で使用して、xxx​​x クラスをロードできます。これは実際には require/include に似ていますが、spl_autoload は複数の拡張子を指定できるため、比較的柔軟です。

    • 前述したように、spl_autoload_registerに含まれる関数ポインタautoload_funcは、使用するローディング関数を指定するために使用されます。次に、対応する関数アドレスを autoload_func に割り当てる必要があります。 spl_autoload_register() は、関数ポインター autoload_func に値を割り当てる関数を実装します。 spl_autoload_register() 関数にパラメータが含まれていない場合、デフォルトでは spl_autoload() を autoload_func に割り当てます

    spl_autoload_call

    • 実際には SPL モジュール内に autoload_functions があり、これは本質的にハッシュ A テーブルであり、または、直観的に理解するために、各要素が読み込み関数へのポインターであるコンテナーとして想像してみましょう。 spl_autoload_call の実装メカニズムは、実際には比較的単純です。これは、特定の順序でコンテナを走査し、各ポインタが実行された後に、内部の関数ポインタが指すロード関数を実行します。読み込みが完了したら終了します。それ以外の場合は、下方向に実行を続けます。すべてのロード関数が実行された後も必要なクラスがまだロードされていない場合、 spl_autoload_call() は直接終了します。つまり、オートロード機構を使用しても、クラスのロードが完了しない可能性があります。重要なのは、オートロード関数を作成する方法です。

    • autoload_functionsがあるので、そこに作成したオートローディング関数を追加するにはどうすればよいでしょうか? spl_autoload と同様に、spl_autoload_register() を使用してロード関数を autoload_functions に登録します。もちろん、登録された関数は、spl_autoload_unregister() 関数を通じて autoload_functions からハッシュ テーブルから削除できます。これは、以前

    に書かれたファクトリー

    設計パターン

    と一致しています。ここで説明する必要があることの 1 つは、spl_autoload_register が自動ロードを実装する順序です。 spl_autoload の自動読み込みシーケンスは次のとおりです。最初に autoload_func が空かどうかを判断し、autoload_func が定義されているかどうかを確認し、定義されていない場合は戻り、autoload() 関数が定義されている場合はエラーを報告します。読み込み結果。 autoload_func が空でない場合、autoload_func ポインタが指す関数は、autoload が定義されているかどうかを確認せずに直接実行されます。 つまり、spl_autoload_register() で登録された関数が最初に使用されます。

    上記の紹介によると、autoload_func が空でない場合、autoload() 関数は自動的に実行できません。 spl_autoload_register() 関数の使用中に autoload() 関数を引き続き使用したい場合は、spl_autoload_register()、つまり spl_autoload_register(autoload()) を通じてハッシュ テーブルに autoload 関数を追加できます。次のコード例は、クラスの通常のメソッドと静的パブリック メソッドをそれぞれ登録する方法を示しています。

      普通函数的注册方法。

    <?php
    
    	/**
    	* @ 普通函数的调用方法,可以调用后缀名分别为.php和.class.php的类文件
    	*/
    	function loadFielEndOfPhp($classname) {
    		$fileName = $classname.".php";
    		if (file_exist($fileName)) {
    			require_once("$fileName");
    		} else {
    			echo $fileName." doesn&#39;t exist!"
    		}
    	}
    
    	function loadFielEndOfClassPhp($classname) {
    		$fileName = $classname.".class.php";
    		if (file_exist($fileName)) {
    			require_once("$fileName");
    		} else {
    			echo $fileName." doesn&#39;t exist!"
    		}
    	spl_autoload_register("loadFielEndOfPhp"); 
    	spl_autoload_register("loadFielEndOfClassPhp");
    
    }

      类中静态的加载函数的注册方法。

    <?php
    
    	/**
    	* @ 类中静态成员函数的调用方法,可调用后缀名为.php和.class.php的文件
    	*/
        class test {
    		public static function loadFielEndOfPhp($classname) {
    			$fileName = $classname.".php";
    			if (file_exist($fileName)) {
    				require_once("$fileName");
    			}
    			else {
    				echo $fileName." doesn&#39;t exist!"
    			}
    		}
    
    		public static function loadFielEndOfClassPhp($classname) {
    			$fileName = $classname.".class.php";
    			if (file_exist($fileName)) {
    				require_once("$fileName");
    			}
    			else {
    				echo $fileName." doesn&#39;t exist!"
    			}
    	}
    	
    	spl_autoload_register(array("test","loadFielEndOfPhp")); 
    	//spl_autoload_register("test::loadFielEndOfPhp");         //上一行的另一种写法,不是使用数组的形式完成注册;
    	spl_autoload_register(array("test","loadFielEndOfClassPhp"));
    	//spl_autoload_register("test::loadFielEndOfClassPhp");    //第三行的另一种写法,不是使用数组的形式完成注册;
    
    }

     

    以上がPHP クラスを自動的にロードする 3 つの方法の詳細な例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。