Laravel・PHP開発

Laravel 11でKernel.phpが廃止された影響とミドルウェア登録の新しい作法

Laravel 11で新しくプロジェクトを作ると、app/Http/Kernel.phpが見当たりません。Laravel 10までの構成を知っていると、ミドルウェアの登録場所が突然なくなったように見えますが、実際に変わったのはミドルウェアの仕組みそのものではありません。新規アプリケーションの初期構造が整理され、これまで複数のファイルに分かれていた起動時の設定が、より少ない場所に集約されたのです。…

Laravel 11でKernel.phpが廃止された影響とミドルウェア登録の新しい作法

ここで最初に整理しておきたい点があります。Laravel 10からLaravel 11へ既存プロジェクトをアップグレードしただけで、app/Http/Kernel.phpが自動的に削除されるわけではありません。Laravel 11では、従来のディレクトリ構造を持つ既存アプリケーションも引き続き動作します。Kernel.phpが最初から存在しないのは、主にLaravel 11の新しいアプリケーションスケルトンで作成したプロジェクトです。

新規プロジェクトでは、ミドルウェアの設定をbootstrap/app.phpに記述します。Laravel 10以前のプロジェクトでは、アップグレード直後からすべてを書き換える必要はありません。旧構造を維持したまま動作を確認し、必要なタイミングで新しい構造へ段階的に寄せることができます。

「スリムなアプリケーション構造」がめざしたもの

Laravel 11の大きな変更として紹介される「スリムなアプリケーション構造」は、初期状態で開発者が確認するファイルを減らすための設計です。従来のLaravelでは、アプリケーションの動作を細かく変更できる一方で、初めてプロジェクトを開いたときに確認すべき設定ファイルも多く存在しました。

ミドルウェアの登録を担っていたapp/Http/Kernel.php、例外処理を担っていたファイルなどが、新しいアプリケーションスケルトンでは標準で用意されなくなっています。これは機能の削除というより、標準設定をフレームワーク側に任せ、アプリケーション側で変更が必要になった部分だけを明示する考え方です。

Laravel 11で変わったのは、ミドルウェアの機能よりも、開発者が設定を置く場所と初期構造です。

Laravelの標準動作をそのまま利用するだけなら、設定ファイルを開かずにアプリケーションを始められます。認証、ルーティング、例外処理、ミドルウェアなどを細かく変更する段階になったときに、必要な設定をbootstrap/app.phpへ追加していく形です。

この構造には、実務上のメリットがあります。プロジェクトの入り口を見たときに、アプリケーション固有の設定と、フレームワークが提供する標準設定の境界が分かりやすくなります。設定ファイルが最初から大量に存在すると、どの部分が実際に変更されているのかを把握するだけでも時間がかかります。変更が必要な場所だけがプロジェクト内に現れるほうが、コードレビューや新しいメンバーの参加時にも追いやすくなります。

ただし、既存プロジェクトをLaravel 11へ更新する場合は話が別です。Laravel 10の構造で作られたアプリケーションには、すでにKernel.phpや例外ハンドラなどが存在します。Laravel 11へアップグレードしても、それらのファイルをフレームワークが勝手に新構造へ変換したり、削除したりするわけではありません。新規作成時の構造と、既存プロジェクトのアップグレード後の構造は分けて考える必要があります。

bootstrap/app.phpによるミドルウェア一元管理の仕組み

Laravel 11の新しいアプリケーションでは、ミドルウェアの設定をbootstrap/app.phpに記述します。起点になるのは、アプリケーションビルダーに対するwithMiddleware()の呼び出しです。

記述の考え方は、bootstrap/app.phpに渡されるミドルウェア設定用のクロージャの中で、$middlewareオブジェクトに対して必要な操作を行うというものです。利用するクラスはIlluminate\Foundation\Configuration\Middlewareです。

たとえば、すべてのHTTPリクエストに適用するミドルウェアを追加する場合は、$middleware->append()または$middleware->prepend()を使います。以前のように、$middleware$middlewareGroupsなどの配列を直接編集するのではなく、何をしたい設定なのかをメソッド名で表現できます。

この違いは、単にファイルの場所が変わっただけではありません。Laravel 10までのKernel.phpでは、プロパティ名と配列の順番を見ながら、どのミドルウェアがどこに追加されているのかを読み解く必要がありました。Laravel 11の構造では、追加、先頭への挿入、グループへの追加、エイリアス登録といった操作が、それぞれ異なるメソッドとして表現されます。

bootstrap/app.phpには、ミドルウェア以外の起動設定も記述できます。たとえば、ルーティングにはwithRouting()、例外処理にはwithExceptions()を使います。アプリケーションの起動時に関わる設定を、ひとつの入り口から追えるようにした構成です。

一方で、サービスプロバイダの登録までbootstrap/app.phpに集約されたわけではありません。Laravel 11の新しい構造では、アプリケーション固有のサービスプロバイダはapp/Providersに置かれ、登録対象はbootstrap/providers.phpで管理されます。ミドルウェアはbootstrap/app.php、サービスプロバイダはbootstrap/providers.phpというように、役割を混同しないことが大切です。

グローバルミドルウェアの追加と順序制御

グローバルミドルウェアは、ルートやコントローラで個別に指定しなくても、すべてのHTTPリクエストに対して実行されるミドルウェアです。リクエストやレスポンスの共通処理、リクエストIDの付与、特定のヘッダー処理など、アプリケーション全体に適用したい処理に使います。

Laravel 11でグローバルミドルウェアを追加するときは、主に次の操作を使い分けます。

  • append()は、既存のグローバルミドルウェアの後ろに追加します。標準の前処理を通したあとで独自処理を実行したい場合に向いています。
  • prepend()は、既存のグローバルミドルウェアより前に追加します。できるだけ早い段階でリクエストを記録したい場合や、後続の処理に渡す情報を先に準備したい場合に使います。
  • remove()は、標準で登録されているグローバルミドルウェアを外すために使います。標準構成を変更する操作なので、削除後に何が失われるかを確認しておく必要があります。
  • replace()は、標準ミドルウェアを別のクラスへ置き換える場合に使います。
  • priority()は、ミドルウェアの優先順位を明示したい場合に使います。

順序は、動作に直接影響します。たとえば、あるミドルウェアがリクエストの内容を読み取り、その結果を後続のミドルウェアが参照するとします。この場合、参照する側が先に実行されると、必要な情報を取得できません。認証、セッション、リクエストの正規化、ログ記録などを組み合わせる場合も、実行順序を曖昧にしないほうが安全です。

Laravelのミドルウェアは、リクエストがミドルウェアを通過してコントローラへ到達し、レスポンスが逆方向に戻る構造です。そのため、単純に配列の上から順に処理が終わるわけではありません。前処理と後処理の両方を持つミドルウェアでは、登録順序がレスポンス側の処理順にも影響します。ログの記録位置やレスポンスヘッダーの付与位置を変更したときは、リクエスト時だけでなくレスポンス時の挙動も確認しておきたいところです。

グローバルミドルウェアの順序は、動けば終わりではなく、前処理と後処理の流れまで含めて設計します。

append()prepend()は便利ですが、どの位置に追加されたかだけを見て判断するのは危険です。Laravelが標準で持つミドルウェアの構成や、アプリケーションで設定済みのグループ、ルート側で指定されたミドルウェアが関係するためです。認証のように処理順が重要なものは、実際のHTTPテストで期待する順序を確認するほうが確実です。

また、グローバルミドルウェアを追加したことを確認するために、php artisan route:listのミドルウェア欄だけを見るのは適切ではありません。この欄が主に示すのは、各ルートに適用されたルートミドルウェアやグループです。append()で追加したグローバルミドルウェアが、常に一覧へ分かりやすく表示されるわけではありません。

確認方法としては、ミドルウェアが付与するヘッダー、ログ、レスポンスの変化、認証やリクエスト変換の結果をHTTPテストで検証します。グローバルミドルウェアが実行されたこと自体を確認したいなら、テスト用の記録処理を組み込む方法もあります。route:listは、特定のルートにauth.adminなどのエイリアスやグループが付いているかを確認する用途に限定して使うのが正確です。

ミドルウェアのエイリアス設定とグループ定義

ルートにミドルウェアを適用するとき、クラス名を毎回そのまま書く代わりに、短い名前を使えるのがエイリアスです。管理画面の認証や権限確認など、複数のルートで繰り返し使うミドルウェアにはエイリアスが適しています。

Laravel 11では、bootstrap/app.phpwithMiddleware()の中でalias()を使って登録します。たとえば、auth.adminという名前を独自の認証ミドルウェアへ対応させる、といった設定です。ルート定義では従来と同じように、middleware('auth.admin')の形式で参照できます。

グループについても同じ場所で定義できます。複数のミドルウェアをひとまとまりにし、ルートやルートグループへまとめて適用したい場合は、group()を使います。既存グループへミドルウェアを加える場合は、appendToGroup()またはprependToGroup()を使う方法があります。

目的Laravel 10までの主な場所Laravel 11の新しいアプリケーション
グローバルミドルウェアの追加app/Http/Kernel.phpの配列bootstrap/app.phpappend()prepend()
エイリアスの登録$middlewareAliasesなどの配列alias()
ミドルウェアグループの定義$middlewareGroupsの配列group()
既存グループへの追加グループ配列を直接編集appendToGroup()prependToGroup()
ルートへの適用ルート側の指定は同じルート側の指定は基本的に同じ

標準のwebapiグループに独自ミドルウェアを追加する場合は、グループ全体を自分で書き直すより、追加位置を明示する方法が扱いやすくなります。既存の構成を保ったまま一つのミドルウェアを加えられるので、フレームワークの標準変更を取り込みやすく、設定差分も小さく保てます。

エイリアスとグループを使うときは、名前の付け方にも注意が必要です。adminauth.adminapi.adminのように似た名前を増やしていくと、ルートを見ただけでは実際に何が実行されるのか判断しづらくなります。認証だけなのか、権限確認まで含むのか、管理画面専用なのかを名前から読み取れるようにしておくと、後からの調査が楽になります。

また、エイリアスはクラスの置き場所を隠すための仕組みでもあります。ルート側の記述が短くなる反面、実際の処理を確認するにはbootstrap/app.phpへ戻る必要があります。重要な認可処理をエイリアスの名前だけで済ませるのではなく、どのミドルウェアがどのルートグループに適用されているかをテストで固定しておくと安心です。

サービスプロバイダの登録場所はミドルウェアと分けて考える

Laravel 11の構造変更を調べていると、ミドルウェア登録とサービスプロバイダ登録を同じ話として扱ってしまうことがあります。しかし、両者は役割も登録場所も異なります。

サービスプロバイダは、コンテナへのバインド、イベントの登録、設定の読み込み、マクロの追加など、アプリケーション起動時の準備を担当します。アプリケーション固有のプロバイダは通常app/Providersに配置し、登録対象をbootstrap/providers.phpに記述します。

Laravel 11の新規アプリケーションでは、標準でアプリケーションプロバイダが登録されている構成を確認できます。独自プロバイダを追加した場合は、bootstrap/providers.phpに登録し、必要に応じてregister()boot()へ処理を実装します。ミドルウェアを追加したいからといって、サービスプロバイダへ処理を移す必要はありません。

反対に、サービスコンテナのバインドをミドルウェア設定のクロージャへ詰め込むのも避けたほうがよいでしょう。bootstrap/app.phpは起動設定の入り口ですが、そこへすべての初期化処理を集めると、ファイルの役割が再び不明確になります。ミドルウェアはwithMiddleware()、ルーティングはwithRouting()、例外処理はwithExceptions()、サービスプロバイダはbootstrap/providers.phpという分担を意識すると、Laravel 11の構成を保ちやすくなります。

既存プロジェクトをアップグレードするときの考え方

Laravel 10からLaravel 11へ移行する場合、最初に行うべきことはKernel.phpを削除することではありません。既存アプリケーションの構成を確認し、Laravel 11で求められる依存関係や設定変更を適用したうえで、現在のミドルウェアが期待通りに動くかを確認します。

旧構造を使っている既存プロジェクトは、その構造を維持したままLaravel 11で動作させられます。これはフレームワークがプロジェクト内のKernel.phpを自動検出して新構造へ切り替える、という意味ではありません。アプリケーションがもともと持っているKernel.phpを含む構成を、そのまま利用できるという互換性です。

新規プロジェクトのbootstrap/app.phpと、Laravel 10から更新したプロジェクトのapp/Http/Kernel.phpを見比べて、ファイルが一致しないことに不安を感じる必要はありません。重要なのは、どちらの構造を使っているかをチーム内で把握し、設定を二重管理しないことです。

既存プロジェクトで新構造へ寄せていく場合は、次のように段階を分けると進めやすくなります。

1. まずcomposer.jsonlaravel/frameworkをLaravel 11に対応する状態へ変更し、依存関係を更新します。

2. 既存のapp/Http/Kernel.php、ルートファイル、サービスプロバイダ、テストを確認し、ミドルウェア登録の現在地を一覧化します。

3. アプリケーションを起動し、主要な画面、認証、管理画面、API、ジョブから呼び出されるHTTP処理などを確認します。

4. 新構造へ移行する場合は、グローバルミドルウェア、エイリアス、グループ、優先順位を種類ごとにbootstrap/app.phpへ移します。

5. ルートに適用されるミドルウェアはroute:listで確認し、グローバルミドルウェアはHTTPテストやログ、レスポンスの内容で確認します。

6. 移行後の挙動を確認してから、不要になった旧設定を整理します。

この順番なら、アップグレード作業と構造変更を一度に行わずに済みます。Laravelのバージョン更新で問題が起きたのか、ミドルウェアの移し替えで問題が起きたのかを切り分けやすくなるためです。

特に、Kernel.phpに独自の処理が多いプロジェクトでは、一括移行を避けたほうがよいでしょう。グローバルミドルウェアとルートミドルウェアを混同しているケース、標準グループを複製して独自グループとして使っているケース、優先順位に依存した認証処理があるケースでは、単純なコピーだけでは同じ挙動にならないことがあります。

移行前に確認したいポイントは次の通りです。

  • グローバルミドルウェアとして登録されているクラスと、その順序
  • webapiなどの標準グループへ追加しているミドルウェア
  • エイリアス名と、それを参照しているルート
  • 優先順位を指定しているミドルウェア
  • terminate()を持つミドルウェアや、レスポンス後の処理
  • テストでwithoutMiddleware()を使っている箇所
  • 環境ごとに登録内容を変えている設定

withoutMiddleware()についても注意が必要です。これは主にルートミドルウェアをテスト時に無効化するための機能で、グローバルミドルウェアを確認したり、無効化したりするための万能な手段ではありません。グローバルミドルウェアのテストでは、実際のリクエストを通してヘッダー、ステータス、ログ、保存されたデータなどを検証するほうが適切です。

設定変更のあとにキャッシュが残っている場合は、設定キャッシュやルートキャッシュをクリアしてから再確認します。config:clearroute:clearは、古い設定が原因なのか、登録方法が原因なのかを切り分ける助けになります。ただし、キャッシュを消せば移行が完了するわけではありません。キャッシュクリアは確認作業の一部であり、登録内容そのものの検証は別に必要です。

Laravel 11のカスタムミドルウェアは登録場所だけが変わる

Kernel.phpが新規プロジェクトに存在しないと、カスタムミドルウェアの作り方まで変わったように感じます。しかし、ミドルウェアクラスの基本はLaravel 10から大きく変わっていません。

php artisan make:middleware EnsureJsonResponseを実行すれば、通常はapp/Http/Middleware/EnsureJsonResponse.phpにクラスが生成されます。クラスのhandle()メソッドでリクエストを受け取り、必要な処理を行って次のミドルウェアやコントローラへ渡すという流れは従来と同じです。

変わるのは、そのクラスをアプリケーションへ登録する場所です。すべてのリクエストに適用するならappend()prepend()、特定の名前でルートから呼び出すならalias()、複数の処理をまとめるならgroup()や既存グループへの追加を使います。

カスタムミドルウェアを作るときは、最初に適用範囲を決めると登録方法を間違えにくくなります。

  • すべてのHTTPリクエストで必要な処理なら、グローバルミドルウェアにします。
  • 管理画面だけ、または特定のAPIだけで必要なら、エイリアスを作ってルートへ適用します。
  • 常に一緒に実行する複数の処理なら、グループとして管理します。
  • 既存のwebapiの処理に追加するだけなら、グループへの追加を検討します。

たとえば、管理者権限の確認を全リクエストへ適用してしまうと、公開ページやヘルスチェックまで影響を受けます。このような処理はグローバルではなく、管理画面のルートグループへエイリアスで適用するほうが自然です。逆に、すべてのレスポンスへ共通のセキュリティヘッダーを付与する処理なら、グローバルミドルウェアとして登録する理由があります。

Laravel 11への移行でロジックまで書き換える必要があるとは限りません。handle()の責務や、リクエストを次へ渡す条件、例外を投げる条件が変わっていないなら、クラスはそのまま利用し、登録部分だけを新しい設定へ移せます。まず登録場所と適用範囲を整理し、その後で必要な変更だけを加えるのが安全です。

実際の動作をどう確認するか

ミドルウェア登録の確認では、コマンドの出力だけに頼らないことが重要です。php artisan route:listは便利なコマンドですが、確認できる範囲があります。

ルート一覧で確認しやすいのは、特定のルートへ付与されたミドルウェア、エイリアス、グループです。たとえば管理画面のルートにauth.adminが付いているか、APIのルートに期待するグループが設定されているかを調べる用途には適しています。

一方、append()prepend()で登録したグローバルミドルウェアについては、ルート一覧のミドルウェア欄を確認するだけでは不十分です。グローバルに実行される処理が実際に呼ばれているかは、次のような方法で確認します。

  • ミドルウェアが付与するレスポンスヘッダーをHTTPテストで検証する
  • テスト用のログや記録先を使い、実行されたことを確認する
  • リクエスト属性やレスポンスの変化を検証する
  • 認証や入力変換など、ミドルウェアが担う結果をエンドツーエンドで確認する
  • 想定外のルートにも適用されていないか、公開ページや例外ページを確認する

順序を検証する場合は、複数のミドルウェアが実行された順番をテストで記録する方法が分かりやすいでしょう。ログの記録だけで確認する場合も、リクエストIDなどを付けておくと、同時に複数のリクエストが流れる環境で追跡しやすくなります。

ルートミドルウェアを一時的に外して原因を切り分ける場合はwithoutMiddleware()が役立ちます。ただし、対象がグローバルミドルウェアなのか、グループやエイリアスを通じて付与されたルートミドルウェアなのかを先に分けて考えてください。ここを混同すると、無効化したつもりの処理が残り、テスト結果を誤って解釈することがあります。

「消えた」のではなく、構造が分かれた

Laravel 11のKernel.php変更は、新規アプリケーションでははっきり目に入ります。しかし、Laravel 10からの既存プロジェクトで同じようにファイルが消えるわけではありません。新規作成時はbootstrap/app.phpを中心としたスリムな構造を使い、既存アプリケーションは旧構造を維持したままアップグレードできる。この二つを分けて理解することが、最初のつまずきを避けるポイントです。

新しいプロジェクトでは、withMiddleware()の中でグローバルミドルウェア、エイリアス、グループ、優先順位を管理します。ルート一覧はルートに付与されたミドルウェアの確認に使い、グローバルミドルウェアはHTTPテストやログ、レスポンスの変化で確認します。サービスプロバイダはbootstrap/providers.phpで管理するため、ミドルウェア設定と同じ場所へ無理に集約しません。

既存プロジェクトでは、アップグレードだけでKernel.phpを削除せず、まず現状の構成で動作を確認します。そのうえで新しい構造へ移行するなら、グローバル登録、グループ、エイリアス、優先順位を一つずつ移し、旧設定を整理する前にテストを通します。自動検出で切り替わる仕組みだと考えなければ、移行の順序も見えやすくなります。

Laravel 11のスリムな構造は、設定を減らすことだけが目的ではありません。標準動作をフレームワークへ任せ、アプリケーション固有の変更だけを適切な場所に書くための構成です。Kernel.phpが存在しないことに驚いたときは、ミドルウェアの仕組みがなくなったと考えるのではなく、まず自分のプロジェクトが新規構造なのか、旧構造を維持した既存プロジェクトなのかを確認してください。

そのうえで、ミドルウェアの適用範囲と実行順序を整理し、bootstrap/app.phpの設定とルート側の指定を分けて確認する。これがLaravel 11でミドルウェアを扱うときの、いちばん事故の少ない作法です。

seoTitle: Laravel 11のミドルウェア登録を解説

metaDescription: Laravel 11でKernel.phpが見当たらない理由と、bootstrap/app.phpでのミドルウェア登録、既存プロジェクトの移行方法を解説します。

Related reading: Laravel・PHP開発をわかりやすく解説.

よくある質問

Laravel 11でKernel.phpが見当たらないのはなぜですか?
Laravel 11の新しいアプリケーションスケルトンでは、初期構造が整理され、設定ファイルがより少ない場所に集約されたためです。機能そのものが削除されたわけではなく、設定の置き場所が変更されました。
既存のLaravel 10プロジェクトを11に上げるとKernel.phpはどうなりますか?
自動的に削除されることはありません。既存プロジェクトは旧構造を維持したまま動作するため、アップグレード直後にファイルを書き換える必要はありません。
Laravel 11でグローバルミドルウェアを追加するにはどうすればいいですか?
bootstrap/app.php内のwithMiddleware()クロージャ内で、append()またはprepend()メソッドを使用して追加します。
ミドルウェアのエイリアスやグループはどこで定義しますか?
bootstrap/app.phpのwithMiddleware()内で、alias()メソッドやgroup()メソッドを使用して定義します。
サービスプロバイダの登録場所もbootstrap/app.phpに変わりましたか?
いいえ、サービスプロバイダの登録はbootstrap/providers.phpで行います。ミドルウェア設定とは役割が異なるため、混同しないように管理する必要があります。

参考情報