#はじめに
実際の開発現場でツールを使うとき、そのツールの仕組みを理解しているとより自信を持てます。アプリケーション開発も同様です。開発ツールの動作を理解していれば、安心して使いこなせます。
このドキュメントの目的は、Laravelフレームワークの仕組みを大まかに理解してもらうことです。フレームワーク全体を知ることで、すべてが「魔法」のように感じられなくなり、自信を持ってアプリケーションを構築できるようになります。すべての用語をすぐに理解できなくても心配いりません。まずは基本的な流れを掴み、他のドキュメントを読み進めるうちに知識が深まります。
#ライフサイクルの概要
#最初のステップ
Laravelアプリケーションへのすべてのリクエストの入口は public/index.php ファイルです。すべてのリクエストはウェブサーバー(Apache / Nginx)の設定によってこのファイルに送られます。index.php ファイル自体は多くのコードを含まず、フレームワークの残りを読み込むための起点となります。
index.php ファイルはComposerが生成したオートローダー定義を読み込み、次に bootstrap/app.php からLaravelアプリケーションのインスタンスを取得します。Laravelが最初に行う処理は、アプリケーション/サービスコンテナのインスタンスを作成することです。
#HTTP / コンソールカーネル
次に、リクエストの種類に応じてHTTPカーネルかコンソールカーネルのどちらかにリクエストが送られます。この2つのカーネルはすべてのリクエストが通過する中心的な場所です。ここではまず、app/Http/Kernel.php にあるHTTPカーネルに注目します。
HTTPカーネルは Illuminate\Foundation\Http\Kernel クラスを継承しており、リクエスト処理前に実行される bootstrappers の配列を定義しています。これらのbootstrappersはエラーハンドリングの設定、ログ設定、アプリケーション環境の検出、その他リクエスト処理前に必要なタスクを行います。通常、これらのクラスはLaravel内部の設定を担当し、開発者が気にする必要はありません。
HTTPカーネルはまた、すべてのリクエストが通過するHTTP ミドルウェアのリストを定義しています。これらのミドルウェアはHTTPセッションの読み書き、メンテナンスモードの判定、CSRFトークンの検証などを処理します。これらについては後ほど詳しく説明します。
HTTPカーネルの handle メソッドのシグネチャは非常にシンプルで、Request を受け取り Response を返します。カーネルはアプリケーション全体を表す大きなブラックボックスのようなもので、HTTPリクエストを与えるとHTTPレスポンスを返します。
#サービスプロバイダー
カーネルの重要な起動処理の一つが、アプリケーションのサービスプロバイダーを読み込むことです。サービスプロバイダーはデータベース、キュー、バリデーション、ルーティングなどフレームワークの各種コンポーネントを起動します。アプリケーションのすべてのサービスプロバイダーは config/app.php の providers 配列で設定されています。
Laravelはこのプロバイダーリストを順に処理し、各プロバイダーをインスタンス化します。インスタンス化後、すべてのプロバイダーの register メソッドが呼ばれます。さらに、すべてのプロバイダーが登録された後に、各プロバイダーの boot メソッドが呼ばれます。これは、boot メソッド実行時にすべてのコンテナバインディングが登録済みで利用可能であることを保証するためです。
Laravelが提供するほぼすべての主要機能はサービスプロバイダーによって起動・設定されます。フレームワークの多くの機能を起動・設定するため、サービスプロバイダーはLaravelの起動プロセスで最も重要な役割を担います。
#ルーティング
アプリケーションで最も重要なサービスプロバイダーの一つが App\Providers\RouteServiceProvider です。このプロバイダーはアプリケーションの routes ディレクトリ内のルートファイルを読み込みます。ぜひ RouteServiceProvider のコードを開いて動作を確認してみてください。
アプリケーションが起動し、すべてのサービスプロバイダーが登録された後、Request はルーターに渡されてディスパッチされます。ルーターはリクエストをルートまたはコントローラーに割り当て、ルート固有のミドルウェアも実行します。
ミドルウェアはアプリケーションに入るHTTPリクエストをフィルタリングや検査する便利な仕組みです。例えば、Laravelにはユーザーが認証済みかを検証するミドルウェアがあります。認証されていなければログイン画面にリダイレクトし、認証済みならリクエストをアプリケーションに進めます。ミドルウェアの中にはHTTPカーネルの $middleware プロパティで全ルートに割り当てられるものもあれば、特定のルートやルートグループにのみ割り当てられるものもあります。詳しくはミドルウェアのドキュメントをご覧ください。
リクエストがマッチしたルートに割り当てられたすべてのミドルウェアを通過すると、ルートまたはコントローラーメソッドが実行され、そのレスポンスがルートのミドルウェアチェーンを通って返されます。
#仕上げ
ルートまたはコントローラーメソッドがレスポンスを返すと、そのレスポンスはルートのミドルウェアを逆方向に通り、アプリケーションがレスポンスを修正・検査する機会を得ます。
最後に、レスポンスがミドルウェアを通過し終えると、HTTPカーネルの handle メソッドがレスポンスオブジェクトを返し、index.php ファイルが返されたレスポンスの send メソッドを呼び出します。send メソッドはレスポンスの内容をユーザーのブラウザに送信します。これでLaravelのリクエストライフサイクルの旅は完了です!
#サービスプロバイダーに注目
サービスプロバイダーはLaravelアプリケーションの起動において本当に重要な役割を果たします。アプリケーションインスタンスが作成され、サービスプロバイダーが登録され、リクエストが起動済みのアプリケーションに渡されます。これだけで非常にシンプルです!
サービスプロバイダーを通じてLaravelアプリケーションがどのように構築・起動されるかをしっかり理解することは非常に価値があります。アプリケーションのデフォルトのサービスプロバイダーは app/Providers ディレクトリに保存されています。
デフォルトでは AppServiceProvider はかなり空です。このプロバイダーはアプリケーション独自の起動処理やサービスコンテナのバインディングを追加するのに最適な場所です。大規模なアプリケーションでは、複数のサービスプロバイダーを作成し、特定のサービスごとにより細かい起動処理を分けることもあります。