L初めてのLaravel

Laravel リクエストライフサイクル

1本のリクエストが、Laravelの中をどう旅するか

ブラウザで開いたページは、Laravelの中でいくつもの部品を順に通って 「返事(レスポンス)」になります。ここではまず全体の流れをひと目で追える概観図を見て、続いて各ステップを1つずつ詳しく図解します。「どこで・何が・なぜ起きるか」をイメージできるようになりましょう。

概観フロー図(まずは全体像)

ブラウザから入ったリクエストが、入口 → 起動 → カーネル → ミドルウェア → ルーティング → コントローラ → レスポンスと進み、復路のミドルウェアを通って ブラウザへ戻るまでを、矢印でつないだ図です。

ブラウザ起動・入口カーネルミドルウェアルーティングコントローラレスポンス
  1. ブラウザURLへアクセス
  2. public/index.php全リクエストの入口
  3. オートローダ読込vendor/autoload.php
  4. アプリ生成bootstrap/app.php
  5. HTTPカーネルApp\Http\Kernel
  6. カーネル起動処理設定/プロバイダ register→boot
  7. ミドルウェア(往路)セッション/CSRF/認証
  8. ルーティングURLに一致するルートを解決
  9. コントローラ検証・モデル・ロジック
  10. レスポンス生成View / JSON
  11. ミドルウェア(復路)逆順で通過
  12. ブラウザへ返却そして terminate

※ ミドルウェアは「往路(行き)」と「復路(帰り)」で2回登場します。行きで通った関所を、 帰りは逆順に通り抜けてブラウザへ戻ります。

ステップ詳細(1つずつ深掘り)

上の各ステップで「何が起きるか / なぜ必要か / 関係する主なファイル・クラス」を 番号順にたどります。左の縦線と番号バッジが、上から下への時間の流れを表します。

  1. すべては public/index.php から始まる

    起動

    何が起きるか

    ユーザーがどのURLを開いても、Webサーバー(Apache/Nginx)はリクエストをこの1つのファイルに渡します。Laravelアプリの「玄関」であり、唯一の入口です。

    なぜ必要か

    入口を1か所にまとめる(フロントコントローラ方式)ことで、共通の初期化・セキュリティ処理を必ず通せます。ページごとにPHPファイルが散らばらないので、管理も安全性も高まります。

    関係する主なファイル・クラス

    • public/index.php
  2. Composer オートローダを読み込む

    起動

    何が起きるか

    index.php が最初に vendor/autoload.php を読み込みます。これで、クラス名を書くだけで対応するPHPファイルが自動で読み込まれるようになります。

    なぜ必要か

    Laravel本体や外部パッケージは何千ものクラスに分かれています。require を手書きせず、必要になった瞬間に自動で読み込む仕組みがないと現実的に動かせません。

    関係する主なファイル・クラス

    • vendor/autoload.php
    • composer.json
  3. アプリケーションインスタンスを生成する

    起動

    何が起きるか

    bootstrap/app.php が実行され、Laravelの中心となるアプリケーション(サービスコンテナ)が1つ作られます。これがアプリ全体の「部品箱」であり、以後あらゆる機能をここから取り出します。

    なぜ必要か

    この箱(コンテナ)があるおかげで、必要なクラスを自動で組み立てて渡す「依存性の注入」が働きます。アプリの土台となる、たった1つの出発点です。

    関係する主なファイル・クラス

    • bootstrap/app.php
    • Illuminate\Foundation\Application
  4. HTTPカーネルがリクエストを受け取る

    往路

    何が起きるか

    生成したアプリからHTTPカーネルを取り出し、handle() にリクエストを渡します。カーネルはリクエスト受付〜レスポンス返却までの全体の司令塔です。

    なぜ必要か

    「入ってきたリクエストを、どんな順番で処理してレスポンスにするか」という一連の流れを1つのクラスに集約するため。ここが処理全体の背骨になります。

    関係する主なファイル・クラス

    • App\Http\Kernel
    • Illuminate\Foundation\Http\Kernel
    • index.php → $kernel->handle($request)
  5. カーネルの起動処理(bootstrap)

    往路

    何が起きるか

    handle() の中で、まず一連の起動処理が走ります。環境変数(.env)と設定(config)の読込、ロギングと例外ハンドラの登録、そして各サービスプロバイダの register→boot が順に行われます。register で部品をコンテナに「登録」し、boot でそれらを「起動」します。この段階でDB接続・ルート定義・認証などアプリの機能が使える状態に整います。

    なぜ必要か

    コントローラが動く前に、設定・DB・ルートなど土台が全部そろっていないと処理できません。register(登録)と boot(起動)を2段階に分けるのは、全プロバイダの登録が終わってから起動することで、機能同士がお互いを安全に参照できるようにするためです。

    関係する主なファイル・クラス

    • config/app.php (providers)
    • app/Providers/*
    • AppServiceProvider::register()
    • AppServiceProvider::boot()
    • RouteServiceProvider
  6. ミドルウェアを往路で通過する

    往路

    何が起きるか

    リクエストはコントローラへ届く前に、ミドルウェアのパイプラインを順番に通ります。まず全リクエスト共通の「グローバルミドルウェア」、続いてルートが属するグループの「ルートミドルウェア」を通過。ここでセッション開始・CSRFトークン確認・認証チェックなどが行われます。各ミドルウェアは「$next($request) を呼ぶ前=往路」「呼んだ後=復路」の両方に処理を書けます。

    なぜ必要か

    「ログインしていなければ弾く」「毎回セッションを用意する」といった共通の前処理を、各コントローラに書かずに1か所へ集約するため。関所を並べるように、通過条件を層で重ねられます。

    関係する主なファイル・クラス

    • App\Http\Kernel ($middleware / $middlewareGroups)
    • app/Http/Middleware/*
    • VerifyCsrfToken
    • Authenticate
    • $next($request)
  7. ルーターがルートを解決しディスパッチ

    往路

    何が起きるか

    ミドルウェアを抜けると、ルーターがリクエストのURLとHTTPメソッドに一致するルートを探します。見つかったルートに紐づくコントローラのメソッド(またはクロージャ)へ処理を振り分け(ディスパッチ)ます。ルートモデルバインディングが設定されていれば、この時点でIDから自動でモデルが取得されます。

    なぜ必要か

    「このURLはこの処理」という対応を1か所(routes)で管理し、URLごとに正しい担当へ確実に届けるため。ルートに専用のミドルウェアを付けることもできます。

    関係する主なファイル・クラス

    • routes/web.php
    • routes/api.php
    • Illuminate\Routing\Router
    • Route::get(...)->controller
  8. コントローラが本処理を実行

    往路

    何が起きるか

    呼ばれたコントローラのメソッドが動きます。フォームリクエストなどで入力値を検証(バリデーション)し、Eloquentモデルでデータベースを読み書きし、必要な計算やビジネスロジックを行います。必要な依存クラスは引数に書くだけでコンテナが自動注入します。

    なぜ必要か

    アプリの「やりたいこと」の本体だからです。ルーティングやミドルウェアが整えた条件のもとで、実際の業務処理をここに書きます(コントローラは薄く保つのがコツ)。

    関係する主なファイル・クラス

    • app/Http/Controllers/*
    • app/Http/Requests/* (FormRequest)
    • app/Models/* (Eloquent)
  9. レスポンスを生成する

    往路

    何が起きるか

    コントローラは処理結果を「レスポンス」として返します。画面ならBladeテンプレートにデータを埋めてHTMLを作り(View)、APIなら配列やモデルをJSONに変換します。返した値はLaravelが Response オブジェクトに整えます。

    なぜ必要か

    ブラウザやアプリが受け取れる形(HTTPレスポンス)にまとめる必要があるため。ここで初めて「返事」の中身が完成します。

    関係する主なファイル・クラス

    • resources/views/*.blade.php
    • Illuminate\Http\Response
    • response()->json(...)
    • return view(...)
  10. レスポンスがミドルウェアを復路で通過

    復路

    何が起きるか

    生成されたレスポンスは、往路で通ったミドルウェアを今度は逆順に通り抜けてブラウザへ向かいます。各ミドルウェアの「$next($request) を呼んだ後」の処理がここで実行され、Cookieやセッションの保存、共通ヘッダーの付与などが行われます。

    なぜ必要か

    往路で始めた処理を締めくくるため。例えば「セッションを開始したなら、最後に保存する」といった後始末を、往路と対になる形で確実に行えます。逆順なのは、後から被せた層を先に外していくイメージです。

    関係する主なファイル・クラス

    • app/Http/Middleware/*
    • StartSession (往路で開始→復路で保存)
    • AddQueuedCookiesToResponse
  11. terminate(終了処理)

    終了

    何が起きるか

    レスポンスがブラウザへ送り返された後、カーネルの terminate() が呼ばれ、「terminable(終了可能)ミドルウェア」の terminate 処理が走ります。ユーザーを待たせずに、セッションのゴミ掃除やログの書き出しなどの後処理を行います。

    なぜ必要か

    レスポンスをできるだけ速くユーザーへ返しつつ、重い後始末は返却後にまわすため。体感速度を保ちながら必要な片付けを済ませられます。

    関係する主なファイル・クラス

    • App\Http\Kernel::terminate()
    • Middleware::terminate($request, $response)

部品どうしの位置関係は全体マップの「MVCとリクエストの流れ」ツリーも参考になります。用語は実務用語集でも確認できます。