RobotLoader: クラスのオートロード
RobotLoaderは、サードパーティのライブラリを含むアプリケーション全体のクラスの自動読み込みを快適に提供するツールです。
- すべての
require
を取り除きます - 必要なスクリプトのみが読み込まれます
- ディレクトリやファイルの命名に関する厳格な規則は必要ありません
- 非常に高速
- 手動でのキャッシュ更新は不要、すべて自動的に行われます
- 成熟し、安定し、広く使用されているライブラリ
したがって、これらのよく知られたコードブロックを忘れることができます:
require_once 'Utils/Page.php';
require_once 'Utils/Style.php';
require_once 'Utils/Paginator.php';
// ...
インストール
RobotLoaderは、単一の独立したファイル
RobotLoader.php
としてダウンロードできます。これをスクリプトにrequire
で含めるだけで、アプリケーション全体の快適なオートロードがすぐに利用可能になります。
require '/path/to/RobotLoader.php';
$loader = new Nette\Loaders\RobotLoader;
// ...
Composerを使用するアプリケーションを構築している場合は、それを使用してインストールできます:
composer require nette/robot-loader
使用法
GoogleボットがWebページをクロールしてインデックスを作成するのと同様に、RobotLoaderもすべてのPHPスクリプトをクロールし、それらに含まれるクラス、インターフェース、トレイト、およびenumを記録します。調査結果はキャッシュに保存され、次のリクエストで使用されます。したがって、どのディレクトリをクロールし、どこにキャッシュを保存するかを指定するだけです:
$loader = new Nette\Loaders\RobotLoader;
// RobotLoader がインデックスを作成するディレクトリ(サブディレクトリを含む)
$loader->addDirectory(__DIR__ . '/app');
$loader->addDirectory(__DIR__ . '/libs');
// キャッシュを 'temp' ディレクトリに設定します
$loader->setTempDirectory(__DIR__ . '/temp');
$loader->register(); // RobotLoader を起動します
これで完了です。これ以降、require
を使用する必要はありません。素晴らしい!
RobotLoaderがインデックス作成中に重複したクラス名に遭遇した場合、例外をスローして通知します。RobotLoaderは、知らないクラスを読み込む必要がある場合にもキャッシュを自動的に更新します。本番サーバーではこれを無効にすることをお勧めします。下記#キャッシュを参照してください。
RobotLoaderに特定のディレクトリをスキップさせたい場合は、$loader->excludeDirectory('temp')
を使用します(複数回呼び出すか、複数のディレクトリを渡すことができます)。
デフォルトでは、RobotLoaderはPHPファイルの構文エラーをParseError
例外をスローして報告します。これは$loader->reportParseErrors(false)
で抑制できます。
Nette アプリケーション
Netteアプリケーション内では、ブートストラップファイルBootstrap.php
で$configurator
オブジェクトが使用されるため、記述を簡略化できます:
$configurator = new Nette\Bootstrap\Configurator;
// ...
$configurator->setTempDirectory(__DIR__ . '/../temp');
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->addDirectory(__DIR__ . '/../libs')
->register();
PHP ファイルアナライザー
RobotLoaderは、オートロード機能を使用せずに、PHPファイル内のクラス、インターフェース、トレイト、およびenumを検索するためだけに使用することもできます:
$loader = new Nette\Loaders\RobotLoader;
$loader->addDirectory(__DIR__ . '/app');
// ディレクトリをクラス/インターフェース/トレイト/enum で検索します
$loader->rebuild();
// クラス => ファイル名のペアの配列を返します
$res = $loader->getIndexedClasses();
このような使用法でもキャッシュを利用できます。これにより、再スキャン時に変更されていないファイルが繰り返し分析されることはありません:
$loader = new Nette\Loaders\RobotLoader;
$loader->addDirectory(__DIR__ . '/app');
// キャッシュを 'temp' ディレクトリに設定します
$loader->setTempDirectory(__DIR__ . '/temp');
// キャッシュを使用してディレクトリを検索します
$loader->refresh();
// クラス => ファイル名のペアの配列を返します
$res = $loader->getIndexedClasses();
キャッシュ
RobotLoaderは、キャッシュを巧みに利用するため、非常に高速です。
開発中は、バックグラウンドで実行されていることにほとんど気づきません。クラスやファイルが作成、削除、名前変更される可能性があることを考慮して、キャッシュを継続的に更新します。そして、変更されていないファイルは繰り返しスキャンしません。
一方、本番サーバーにデプロイする場合は、ファイルが変更されないため、$loader->setAutoRefresh(false)
を使用してキャッシュの更新を無効にすることをお勧めします(Netteアプリケーションでは自動的に行われます)。同時に、新しいバージョンをホスティングにアップロードする際には、キャッシュを削除する必要があります。
キャッシュがまだ存在しない場合の最初のファイルスキャンは、より大規模なアプリケーションでは当然少し時間がかかることがあります。RobotLoaderには、「キャッシュスタンピード」:https://en.wikipedia.org/…che_stampedeに対する組み込みの防止策があります。 これは、本番サーバーで多数の同時リクエストが発生し、RobotLoaderが起動され、キャッシュがまだ存在しないため、すべてがファイルのスキャンを開始する状況です。これはサーバーに過度の負荷をかけることになります。 幸いなことに、RobotLoaderは、複数の同時リクエストが発生した場合、最初のスレッドのみがファイルをインデックス化し、キャッシュを作成し、他のスレッドは待機してその後キャッシュを利用するように機能します。
PSR-4
現在、PSR-4に準拠していれば、オートロードに Composer
を使用できます。簡単に言えば、これは名前空間とクラス名がディレクトリ構造とファイル名に対応するシステムです。つまり、例えばApp\Core\RouterFactory
は/path/to/App/Core/RouterFactory.php
ファイルにあります。
RobotLoaderは固定構造に縛られていないため、PHPの名前空間と同じように設計されたディレクトリ構造を持つことが完全に適していない状況や、歴史的にそのような規則を使用していないアプリケーションを開発している場合に役立ちます。両方のローダーを一緒に使用することも可能です。