PHP
オートローディングプライマー
サーチ…
構文
- 要求する
- spl_autoload_require
備考
オートロードは、フレームワーク戦略の一環として、書かなければならない定型コードの量を容易にします。
インラインクラス定義、ロード不要
// zoo.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
$animal = new Animal();
$animal->eats('meat');
PHPはnew Animal
ファイルを実行する前にAnimal
が何であるかを知っています。PHPがソースファイルをトップからボトムまで読み込むためです。しかし、定義されているソースファイルだけでなく、多くの場所で新しいAnimalsを作成したい場合はどうでしょうか?これを行うには、クラス定義をロードする必要があります。
必要な手動クラスロード
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// zoo.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('slop');
// aquarium.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('shrimp');
ここには3つのファイルがあります。 1つのファイル( "Animal.php")がクラスを定義します。このファイルには、クラスを定義するだけでなく、副作用がなく、「動物」についての知識がすべて1つの場所に整えられます。それは簡単にバージョン管理されています。簡単に再利用できます。
2つのファイルは、手動でファイルをrequire
により、 "Animal.php"ファイルを消費します。ここでも、PHPはソースファイルをトップからボトムまで読み込むので、requireは "Animal.php"ファイルを見つけて、 new Animal
呼び出す前にAnimal
クラス定義を利用可能にします。
new Animal
をやりたいと思っていた数十、数百のケースがあったとしましょう。それはコードを書くのが非常に面倒な多くの、多くのrequire
ステートメントをrequire
します。
オートローディングはマニュアルクラス定義の読み込みを置き換えます
// autoload.php
spl_autoload_register(function ($class) {
require_once "$class.php";
});
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// zoo.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('slop');
// aquarium.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('shrimp');
これを他の例と比較する。 require "Animal.php"
がrequire "autoload.php"
に置き換えられていることに注意してください。実行時には外部ファイルも含めていますが、 特定のクラス定義を含めるのではなく 、 すべてのクラスを含むことができるロジックが含まれています 。私たちの開発を容易にする間接的なレベルです。代わりに1が書くのrequire
我々が必要とするすべてのクラスのために、我々は1つが書き込みをrequire
するすべてのクラスのために。 N require
を1 require
置き換えることができrequire
。
魔法はspl_autoload_registerで起こります。このPHP関数はクロージャを取り、クロージャのキューにクロージャを追加します 。 PHPが定義を持たないクラスに遭遇すると、PHPはクラス名をキュー内の各クロージャに渡します。クロージャを呼び出した後にクラスが存在する場合、PHPは以前のビジネスに戻ります。キュー全体を試した後にクラスが存在しない場合、PHPは「Class 'Whatever' Not Found」でクラッシュします。
フレームワークソリューションの一部としてオートローディング
// autoload.php
spl_autoload_register(function ($class) {
require_once "$class.php";
});
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// Ruminant.php
class Ruminant extends Animal {
public function eats($food) {
if ('grass' === $food) {
parent::eats($food);
} else {
echo "Yuck, $food!";
}
}
}
// Cow.php
class Cow extends Ruminant {
}
// pasture.php
require 'autoload.php';
$animal = new Cow;
$animal->eats('grass');
一般的なオートローダーのおかげで、私たちのオートローダー命名規則に従ったクラスにアクセスすることができます。この例では、慣習は簡単です:目的のクラスは、クラス名と同じディレクトリにあり、 ".php"で終わるファイルを持つ必要があります。クラス名がファイル名と完全に一致することに注意してください。
オートローディングを行わなければ、手動で基本クラスをrequire
とします。動物園の動物園全体を構築した場合、単一のオートローダーで簡単に置き換えることができる何千ものrequireステートメントがあります。
最終的な分析では、PHPオートローディングは、機械的なコードを少なく書くことができるようにするためのメカニズムで、ビジネス上の問題の解決に集中できます。 クラス名をファイル名にマップする戦略を定義するだけです。ここで行ったように、独自の自動ロード戦略をロールバックすることができます。または、PHPコミュニティで採用されている標準のPSR-0またはPSR-4を使用できます。あるいは、 コンポーザーを使用して、これらの依存関係を総称的に定義して管理することができます。
Composerを使ったオートロード
Composerはvendor/autoload.php
ファイルを生成します。
あなたは単にこのファイルを含めることができ、あなたは無料でオートローディングを受けるでしょう。
require __DIR__ . '/vendor/autoload.php';
これにより、サードパーティの依存関係を簡単に処理できます。
autoloadセクションをcomposer.json
追加することで、オートローダに独自のコードを追加することもできます。
{
"autoload": {
"psr-4": {"YourApplicationNamespace\\": "src/"}
}
}
このセクションでは、オートロードマッピングを定義します。この例では、名前空間のディレクトリへのPSR-4マッピングがあります/src
ディレクトリは、 /vendor
ディレクトリと同じレベルのプロジェクトルートフォルダにあります。サンプルのファイル名は、 YourApplicationNamespace\Foo
クラスを含むsrc/Foo.php
です。
重要: autoloadセクションに新しいエントリを追加した後、 dump-autoload
コマンドを再実行して、 vendor/autoload.php
ファイルを再生成して新しい情報で更新する必要があります。
PSR-4
オートローディングに加えて、ComposerはPSR-0
、 classmap
、およびfiles
自動ロードをclassmap
していfiles
。詳細については、 オートロードリファレンスを参照してください。
/vendor/autoload.php
ファイルをインクルードすると、Composer Autoloaderのインスタンスが返されます。インクルード呼び出しの戻り値を変数に格納し、さらに名前空間を追加することができます。これは、例えば、テストスイート内のクラスのオートローディングに便利です。
$loader = require __DIR__ . '/vendor/autoload.php';
$loader->add('Application\\Test\\', __DIR__);