ホームページ  >  記事  >  バックエンド開発  >  PHPクラスの自動ロード機構の例を詳しく解説

PHPクラスの自動ロード機構の例を詳しく解説

伊谢尔伦
伊谢尔伦オリジナル
2017-07-01 09:18:551360ブラウズ

PHPのクラス自動読み込みの仕組み

PHPの開発プロセス中、外部からクラスを導入したい場合は、通常、includeメソッドとrequireメソッドを使用して、このクラスを定義するファイルをインクルードします。小規模に開発する場合には大きな問題はありません。しかし、大規模な開発プロジェクトでは、これを行うと大量の require メソッド呼び出しまたは include メソッド呼び出しが生成され、効率が低下するだけでなく、コードの保守が困難になります。さらに、require_once は非常に高価です。

PHP5 より前では、各 PHP フレームワークが

クラス の自動ロードを実装したい場合、通常、特定の合意に従って トラバース ディレクトリ を実装し、合意されたルールに準拠するすべてのファイルのクラスまたは関数を自動的にロードしていました。 もちろん、PHP5 より前のオブジェクト指向のサポートはあまり良くなく、クラスの使用は現在ほど頻繁ではありませんでした。 PHP5 以降では、PHP クラスをロードするときに、クラスが配置されているファイルが含まれていない場合、またはクラス名が間違っている場合、Zend エンジンは自動的に autoload 関数を呼び出します。この機能を使用するには、ユーザー自身がオートロード機能を実装する必要があります。 PHP5.1.2以降では、spl_autoload_register関数を使用して自動ロード処理機能をカスタマイズできるようになりました。この関数が呼び出されない場合、SPL のカスタム spl_autoload 関数がデフォルトで使用されます。

1. オートロードの例:

function autoload($class_name) {
   echo &#39;autload class:&#39;, $class_name, &#39;<br />&#39;;
}

new Demo();

上記のコードは最後に autoload class:Demo を出力します。

その後、エラーが報告されます: Fatal error: Class 'Demo' not found

通常、次のように _autoload

を使用してクラスを自動的にロードします:

<?php 

  function autoload($class_name) { 
       require_once ($class_name . “class.php”); 
  } 
   $memo= new Demo();  

_autoload は少なくとも 3 つのことを実行する必要があることがわかります。 1 つ目は、クラス名に基づいてクラス ファイル名を決定することです。2 つ目は、クラス ファイルが配置されているディスク パスを決定することです (この場合は最も単純なケースで、クラスは同じフォルダー内にあります)。 2 番目のことは、クラスをディスク ファイルからシステムにロードすることです。 3 番目のステップは最も単純で、include/require を使用するだけです。第 1 ステップと第 2 ステップの機能を実現するには、クラス名とディスク ファイル間のマッピング方法を開発時に合意する必要があります。この方法でのみ、クラス名に基づいて対応するディスク ファイルを見つけることができます。

したがって、含めるクラス ファイルが多数ある場合は、対応するルールを決定し、autoload() 関数でクラス名と実際のディスク ファイルを一致させるだけで、遅延読み込み効果を実現できます。ここから、 autoload() 関数の実装で最も重要なことは、クラス名と実際のディスク ファイルの間のマッピング ルールの実装であることもわかります。

しかし、ここで問題が発生します。システムの実装で他の多くのクラス ライブラリを使用する必要がある場合、これらのクラス ライブラリは異なる開発エンジニアによって開発される可能性があり、クラス名と実際のディスク ファイルの間のマッピング ルールは次のとおりです。違うのと同じ。現時点で、クラス ライブラリ ファイルの自動ロードを実装したい場合は、すべてのマッピング ルールを autoload() 関数に実装する必要があるため、autoload() 関数は非常に複雑になるか、実装が不可能になる可能性があります。最終的に、autoload() 関数は実装できたとしても非常に肥大化する可能性があり、将来のメンテナンスとシステム効率に大きな悪影響を及ぼします。この場合、

SPL 標準ライブラリが PHP5 で導入され、新しいソリューションは spl_autoload_register() 関数です。

2. spl_autoload_register() 関数


この関数の機能は、関数を SPL 自動ロード関数スタックに登録し、システムのデフォルトの autoload() 関数を削除することです。これは以下の例で見ることができます:

function autoload($class_name) {
    echo &#39;autload class:&#39;, $class_name, &#39;<br />&#39;;
}
function classLoader($class_name) {
    echo &#39;SPL load class:&#39;, $class_name, &#39;<br />&#39;;
}
spl_autoload_register(&#39;classLoader&#39;);
new Test();//结果:SPL load class:Test

语法:bool  spl_autoload_register ( [callback $autoload_function] )    接受两个参数:一个是添加到自动加载栈的函数,另外一个是加载器不能找到这个类时是否抛出异常的标志。第一个参数是可选的,并且默认指向spl_autoload()函数,这个函数会自动在路径中查找具有小写类名和.php扩展或者.ini扩展名,或者任何注册到spl_autoload_extensions()函数中的其它扩展名的文件。

<?php  
class CalssLoader   
{   
    public static function loader($classname)   
    {   
        $class_file = strtolower($classname).".php";   
        if (file_exists($class_file)){   
            require_once($class_file);   
        }   
    }   
}    
// 方法为静态方法   
spl_autoload_register(&#39;CalssLoader::loader&#39;);    
$test = new Test();

      一旦调用spl_autoload_register()函数,当调用未定义类时,系统会按顺序调用注册到spl_autoload_register()函数的所有函数,而不是自动调用autoload()函数。如果要避免这种情况,需采用一种更加安全的spl_autoload_register()函数的初始化调用方法:

if(false === spl_autoload_functions()){    
    if(function_exists(&#39;autoload&#39;)){    
        spl_autoload_registe(&#39;autoload&#39;,false);    
    }    
 }

spl_autoload_functions()函数会返回已注册函数的一个数组,如果SPL自动加载栈还没有被初始化,它会返回布尔值false。然后,检查是否有一个名为autoload()的函数存在,如果存在,可以将它注册为自动加载栈中的第一个函数,从而保留它的功能。之后,可以继续注册自动加载函数。

还可以调用spl_autoload_register()函数以注册一个回调函数,而不是为函数提供一个字符串名称。如提供一个如array('class','method')这样的数组,使得可以使用某个对象的方法。

下一步,通过调用spl_autoload_call('className')函数,可以手动调用加载器,而不用尝试去使用那个类。这个函数可以和函数class_exists('className',false)组合在一起使用以尝试去加载一个类,并且在所有的自动加载器都不能找到那个类的情况下失败。

f(spl_autoload_call(&#39;className&#39;) && class_exists(&#39;className&#39;,false)){    
  
    } else {    
    }

SPL自动加载功能是由spl_autoload() ,spl_autoload_register(), spl_autoload_functions() ,spl_autoload_extensions()和spl_autoload_call()函数提供的。


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

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