Bootstrap
Bootstrapは、環境を初期化し、依存性注入(DI)コンテナを作成し、アプリケーションを起動するブートコードです。ここでは以下について説明します。
- NEONファイルを使用した設定方法
- 本番環境と開発環境の区別方法
- DIコンテナの作成方法
Webアプリケーションであれ、コマンドラインから実行されるスクリプトであれ、アプリケーションはその実行を開始する際に何らかの形で環境を初期化します。昔は、例えば
include.inc.php
のようなファイルがこれを担当し、最初のファイルがインクルードしていました。
最新のNetteアプリケーションでは、これは Bootstrap
クラスに置き換えられ、アプリケーションの一部として app/Bootstrap.php
ファイルにあります。例えば、次のようになります。
use Nette\Bootstrap\Configurator;
class Bootstrap
{
private Configurator $configurator;
private string $rootDir;
public function __construct()
{
$this->rootDir = dirname(__DIR__);
// Configuratorはアプリケーション環境とサービスの設定を担当します。
$this->configurator = new Configurator;
// Netteによって生成される一時ファイル(コンパイルされたテンプレートなど)のディレクトリを設定します。
$this->configurator->setTempDirectory($this->rootDir . '/temp');
}
public function bootWebApplication(): Nette\DI\Container
{
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}
private function initializeEnvironment(): void
{
// Netteは賢く、開発モードは自動的に有効になります。
// または、次の行のコメントを解除して特定のIPアドレスに対して有効にすることもできます。
// $this->configurator->setDebugMode('secret@23.75.345.200');
// Tracyを有効にします:デバッグのための究極の「スイスアーミーナイフ」。
$this->configurator->enableTracy($this->rootDir . '/log');
// RobotLoader: 選択したディレクトリ内のすべてのクラスを自動的にロードします。
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
}
private function setupContainer(): void
{
// 設定ファイルをロードします。
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
}
}
index.php
Webアプリケーションの場合、最初のファイルは www/
公開ディレクトリ にある
index.php
です。これは Bootstrap
クラスに環境を初期化させ、DIコンテナを作成させます。その後、そこから Application
サービスを取得し、Webアプリケーションを起動します。
$bootstrap = new App\Bootstrap;
// 環境の初期化 + DIコンテナの作成
$container = $bootstrap->bootWebApplication();
// DIコンテナは Nette\Application\Application オブジェクトを作成します
$application = $container->getByType(Nette\Application\Application::class);
// Netteアプリケーションを起動し、受信リクエストを処理します
$application->run();
ご覧のとおり、環境の設定と依存性注入(DI)コンテナの作成は、Nette\Bootstrap\Configurator クラスによって支援されます。これについて詳しく見ていきましょう。
開発環境 vs 本番環境
Netteは、開発サーバーで実行されているか、本番サーバーで実行されているかによって動作が異なります。
- 🛠️ 開発環境 (Development)
- 役立つ情報(SQLクエリ、実行時間、使用メモリ)を含むTracyデバッグバーを表示します。
- エラーが発生した場合、関数呼び出しと変数内容を含む詳細なエラーページを表示します。
- Latteテンプレートの変更、設定ファイルの編集などがあった場合にキャッシュを自動的に更新します。
- 🚀 本番環境 (Production)
- デバッグ情報は表示せず、すべてのエラーをログに記録します。
- エラーが発生した場合、ErrorPresenterまたは一般的な「Server Error」ページを表示します。
- キャッシュは自動的に更新されません!
- 速度とセキュリティのために最適化されています。
モードの選択は自動検出によって行われるため、通常は何も設定したり手動で切り替えたりする必要はありません。
- 開発環境: localhost(IPアドレス
127.0.0.1
または::1
)で、プロキシが存在しない場合(つまり、そのHTTPヘッダーがない場合)。 - 本番環境: それ以外のすべての場合。
他の場合、例えば特定のIPアドレスからアクセスするプログラマーに対して開発環境を有効にしたい場合は、setDebugMode()
を使用します。
$this->configurator->setDebugMode('23.75.345.200'); // IPアドレスの配列も指定できます
IPアドレスとCookieを組み合わせることを強くお勧めします。nette-debug
Cookieに秘密のトークン、例えば secret1234
を保存し、この方法で特定のIPアドレスからアクセスし、かつCookieに言及されたトークンを持つプログラマーに対して開発環境を有効にします。
$this->configurator->setDebugMode('secret1234@23.75.345.200');
localhostに対しても、開発環境を完全に無効にすることもできます。
$this->configurator->setDebugMode(false);
注意:値 true
は開発環境を強制的に有効にします。これは本番サーバーでは絶対に行ってはいけません。
デバッグツール Tracy
簡単なデバッグのために、優れたツールTracyを有効にします。開発環境ではエラーを視覚化し、本番環境では指定されたディレクトリにエラーをログ記録します。
$this->configurator->enableTracy($this->rootDir . '/log');
一時ファイル
NetteはDIコンテナ、RobotLoader、テンプレートなどにキャッシュを使用します。したがって、キャッシュが保存されるディレクトリへのパスを設定する必要があります。
$this->configurator->setTempDirectory($this->rootDir . '/temp');
LinuxまたはmacOSでは、log/
および temp/
ディレクトリに書き込み権限を設定してください。
RobotLoader
通常、RobotLoaderを使用してクラスを自動的にロードしたいので、それを起動し、Bootstrap.php
が配置されているディレクトリ(つまり
__DIR__
)とそのすべてのサブディレクトリからクラスをロードさせます。
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
代替アプローチは、PSR-4に準拠しながらComposer経由でのみクラスをロードさせることです。
タイムゾーン
Configuratorを使用して、デフォルトのタイムゾーンを設定できます。
$this->configurator->setTimeZone('Europe/Prague');
DIコンテナの設定
ブートプロセスの一部は、アプリケーション全体の心臓部であるDIコンテナ、つまりオブジェクトのファクトリを作成することです。これは実際にはNetteによって生成され、キャッシュディレクトリに保存されるPHPクラスです。ファクトリはアプリケーションの主要なオブジェクトを生成し、設定ファイルを使用してそれらをどのように作成および設定するかを指示することで、アプリケーション全体の動作に影響を与えます。
設定ファイルは通常、NEON形式で記述されます。別の章で、設定できるすべてのことについて学びます。
開発環境では、コードまたは設定ファイルが変更されるたびにコンテナが自動的に更新されます。本番環境では、一度だけ生成され、パフォーマンスを最大化するために変更はチェックされません。
addConfig()
を使用して設定ファイルをロードします。
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
複数の設定ファイルを追加したい場合は、addConfig()
関数を複数回呼び出すことができます。
$configDir = $this->rootDir . '/config';
$this->configurator->addConfig($configDir . '/common.neon');
$this->configurator->addConfig($configDir . '/services.neon');
if (PHP_SAPI === 'cli') {
$this->configurator->addConfig($configDir . '/cli.php');
}
cli.php
という名前はタイプミスではありません。設定はPHPファイルに記述することもでき、そのファイルが配列として返します。
`includes` セクション |dependency-injection:configurationで他の設定ファイルを追加することもできます。
設定ファイルに同じキーを持つ要素が表示された場合、それらは上書きされるか、配列の場合はマージされます。後でインクルードされたファイルは、前のファイルよりも優先度が高くなります。includes
セクションが記載されているファイルは、それにインクルードされているファイルよりも優先度が高くなります。
静的パラメータ
設定ファイルで使用されるパラメータは、 `parameters`
セクション|dependency-injection:configurationで定義でき、addStaticParameters()
メソッド(エイリアス addParameters()
を持つ)で渡す(または上書きする)こともできます。重要なのは、パラメータの値が異なると、追加のDIコンテナ、つまり追加のクラスが生成されることです。
$this->configurator->addStaticParameters([
'projectId' => 23,
]);
projectId
パラメータは、設定で通常の %projectId%
表記で参照できます。
動的パラメータ
コンテナに動的パラメータを追加することもできます。静的パラメータとは異なり、それらの異なる値は新しいDIコンテナの生成を引き起こしません。
$this->configurator->addDynamicParameters([
'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);
このようにして、例えば環境変数を簡単に追加でき、それらは設定で %env.variable%
表記で参照できます。
$this->configurator->addDynamicParameters([
'env' => getenv(),
]);
デフォルトパラメータ
設定ファイルでは、これらの静的パラメータを使用できます。
%appDir%
はBootstrap.php
ファイルを含むディレクトリへの絶対パスです。%wwwDir%
はエントリファイルindex.php
を含むディレクトリへの絶対パスです。%tempDir%
は一時ファイル用のディレクトリへの絶対パスです。%vendorDir%
はComposerがライブラリをインストールするディレクトリへの絶対パスです。%rootDir%
はプロジェクトのルートディレクトリへの絶対パスです。%debugMode%
はアプリケーションがデバッグモードであるかどうかを示します。%consoleMode%
はリクエストがコマンドライン経由で来たかどうかを示します。
インポートされたサービス
ここではさらに深く掘り下げます。DIコンテナの目的はオブジェクトを作成することですが、例外的に既存のオブジェクトをコンテナに挿入する必要がある場合があります。これを行うには、imported: true
フラグを使用してサービスを定義します。
services:
myservice:
type: App\Model\MyCustomService
imported: true
そして、ブートストラップでオブジェクトをコンテナに挿入します。
$this->configurator->addServices([
'myservice' => new App\Model\MyCustomService('foobar'),
]);
異なる環境
必要に応じて Bootstrap
クラスを自由に変更してください。bootWebApplication()
メソッドにパラメータを追加して、Webプロジェクトを区別することができます。または、他のメソッドを追加することもできます。例えば、単体テスト用の環境を初期化する
bootTestEnvironment()
、コマンドラインから呼び出されるスクリプト用の
bootConsoleApplication()
などです。
public function bootTestEnvironment(): Nette\DI\Container
{
Tester\Environment::setup(); // Nette Testerの初期化
$this->setupContainer();
return $this->configurator->createContainer();
}
public function bootConsoleApplication(): Nette\DI\Container
{
$this->configurator->setDebugMode(false);
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}