オートローディングとは; spl_autoload、__ autoload、spl_autoload_registerはどのように使用しますか?


204

私は高度なPHP標準を学び、新しくて便利なメソッドを実装しようとしています。以前は__autoload各ページに複数のファイルを含めてエスケープするためだけに使用していましたが、最近ヒントが表示されました__autoload manual

spl_autoload_register()は、クラスをオートロードするためのより柔軟な代替手段を提供します。このため、__ autoload()の使用は推奨されておらず、将来廃止されるか削除される可能性があります。

しかし、私は実際に実装する方法を見つけ出すことはできませんspl_autoloadし、spl_autoload_register

回答:


335

spl_autoload_register() PHPがスタック/キューに入れ、「新しいクラス」が宣言されたときに順次呼び出す複数の関数(または独自のAutoloadクラスの静的メソッド)を登録できます。

だから例えば:

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
    $path = '/path/to/class/';

    include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();

上記の例では、「MyClass」はインスタンス化しようとしているクラスの名前です。PHPはこの名前を文字列としてに渡しspl_autoload_register()ます。これにより、変数を取得して、適切なクラス/ファイルを「含める」ことができます。 。その結果、include / requireステートメントを介してそのクラスを具体的に含める必要はありません...

上記の例のように、インスタンス化するクラスを呼び出すだけspl_autoload_register()で、すべてのクラスの場所を特定する独自の関数を(を介して)登録したので、PHPはその関数を使用します。

を使用する利点spl_autoload_register()は、__autoload()作成するすべてのファイルにオートロード機能を実装する必要がないことです。spl_autoload_register()また、複数のオートロード関数を登録して、オートロードを高速化し、さらに簡単にすることもできます。

例:

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
    public static function ClassLoader($className)
    {
         //your loading logic here
    }


    public static function LibraryLoader($className)
    {
         //your loading logic here
    }

spl_autoloadに関して、マニュアルは次のように述べています:

この関数は、のデフォルト実装として使用することを目的としています__autoload()。他に何も指定さspl_autoload_register()れておらず、パラメータなしで呼び出された場合、この関数はその後のの呼び出しに使用されます__autoload()

より実用的には、すべてのファイルが単一のディレクトリにあり、アプリケーションが.phpファイルだけでなく、たとえば.inc拡張子を持つカスタム構成ファイルを使用する場合、使用できる1つの戦略は、すべてを含むディレクトリを追加することです。 PHPのインクルードパスへのファイル(経由set_include_path())。
また、構成ファイルも必要なため、spl_autoload_extensions()PHPで検索する拡張機能をリストするために使用します。

例:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();

spl_autoloadは__autoload()magicメソッドのデフォルトの実装であるため、新しいクラスをインスタンス化しようとすると、PHPはspl_autoloadを呼び出します。

お役に立てれば...


35
これは、これまでの回答の歴史の中で最高の回答の1つかもしれません。尊敬。「OMG!それは今ではすべて理にかなっています!」あなたのための瞬間、私の良い男。ファンクラブを始めようかな。
Just Plain High

2
これを代替のユニバースでさえもすべての回答の中で最良の回答にするために、spl_autoloadを追加してください、ええと、「役立つ」(?)はすべてのファイル名を小文字に変換します(以下の@userへの私のコメントを参照)。CapitalLettersAndStuffが好きな場合は、spl_autoload_register()バニラを使用できません。
Just Plain High

6
@Just Plain High私にはその問題はなく、すべてのクラスファイルはキャメルケース化されています。ところで、これは素晴らしい答えです。これは、この投稿を読むまで理解できない単純な概念を理解するのに役立ちました。私のすべてのクラスファイルを含む私の85(および成長中)行のインクルードファイルは7行になりました。
カイル

2
これは確かに良い答えですが、1つ欠けています。実際のデフォルト機能は何ですか?私が知っているクラスでは、パスとして名前空間を使用し、ファイル名としてクラス名を使用します。それが関数でどのように機能するかはわかりませんが。
SiXoS 14年

2
レイジーロードインクルードファイル/クラスを使用する(そして一般に)ことの大きなメリットの1つではないですか?これは答えによって暗示されていますが、明示的には述べられていません。私にとって、これはあなたの回答に含めるのに最適な重要な情報です!:)spl_autoload_register()__autoload()
rinogo 2015

13

PHP 5.3以降spl_autoload_register()、名前空間を使用できるようになりました。つまり、プロジェクトを整理し、phpクラスをオートロードして、__autoload()関数を再定義したり、要求したり、含めたりする必要がありません。

この動作を説明するには、index.phpというファイルを作成します。

<?php
spl_autoload_register();
var_dump(new Main\Application);

次に、index.phpファイルのすぐ隣にMainという名前のフォルダーを作成します。最後に、MainにあるApplication.phpというファイルを作成し、次のコードをそのファイルに貼り付けます。

<?php namespace Main;
class Application{}

9
このすべてをいじるときのメモ:spl_autoload()-したがって、spl_autoload_register()-ファイル名を小文字に変換します(バグレポート、嘆願、激しい投票にもかかわらず)。これは、「Main \ Application」を探している可能性があるが、spl_autoloadは「main \ application」を探していることを意味します。ラクダが好きなら、私と同じように、独自の関数を作成する必要があります。素敵なスターター例はここにあります:github.com/ircmaxell/PHP-CryptLib/blob/...
単なるハイ

1
長所:spl_autoload_register()は、短所を自動ロードする最速の方法です。このファイルは、小文字のファイル/クラス、およびネームスペースでのみ機能します。これは、現在のところ、非常に長い時間です(キャメルケースなどを使用するように指示するオプションはありません)。ただし、namespace / classname.php構造を使用できる場合は、これ以上見てはいけません。
スタムスター2016

1
spl_autoload_register()デフォルトの実装では、継承されたクラスを見つけることができません。したがって、デフォルト、小文字のファイル、およびネームスペースパスを反映するディレクトリを使用すると、別のクラス(親)を拡張するクラスがない限り、すべてが正常に機能します。PHPは、それらがすべて同じディレクトリ/名前空間にある場合でも、その親クラスを見つけることができないというエラーをスローします!混乱しているのは、文字通り第1レベルのクラスしか見つからないためspl_autoload_register()、欠落している親/継承クラスを手動で含めるために、最初のクラスの直後に匿名関数のルールを追加する必要があったことです。
スタムスター2017

1

Autoloadの使用方法は次のとおりです。与えられた例では、3つの異なるディレクトリからクラスをロードしたいと思います。

function namespaceAutoload($rawClass){

$class = str_replace('\\', DIRECTORY_SEPARATOR, $rawClass);

$possiblePaths[] = '..\sys\class\file.php';
$possiblePaths[] = '..\sys\class\lib\file.php';
$possiblePaths[] = '..\sys\class\class.file.inc.php';

foreach ($possiblePaths as $templatePath) {
    $path = str_replace(["\\", "file"], [DIRECTORY_SEPARATOR, $class], $templatePath);
    if (file_exists($path)) {
        require_once "$path";
        break;
    }
} spl_autoload_register("namespaceAutoload"); 

与えられた例では、PHPはこれら3つの異なるファイル名形式を使用して、これら3つのディレクトリで名前空間\クラスを探します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.