Laravel 13のappディレクトリ構成を整理する:標準構成と機能別構成の選び方
作成日:2026.08.19
Laravel 13のappディレクトリの基本を確認し、標準的なapp/Httpと、管理画面などの機能単位で分けるapp/Admin/Httpの違いを解説します。Controller、Form Request、Service、Action、Modelの配置例を通して、それぞれの特徴と使い分けを整理します。
目次
LaravelでControllerやModelを追加していくと、app/の中にどのような基準でディレクトリを作ればよいのか迷うことがあります。
例えば、Laravelの標準的なapp/Http/Controllersを使う構成と、管理画面に関係するコードをapp/Admin/Http/Controllersへまとめる構成では、ディレクトリを分ける考え方が異なります。
今回はLaravel 13のapp/の基本構成を確認し、app/Httpとapp/Admin/Httpをどのように使い分けるか考えてみます。
前提
この記事では、以下の環境を対象にします。
- OS: Windows 11
- PHP: 8.3.15
- Composer: 2.5.4
- Laravel Framework: 13.x
- ターミナル: PowerShell
- プロジェクト名:
laravel-example
Laravelプロジェクトの作成、ルーティング、Controller、Bladeの基本については、以前の記事「Windows 11でLaravel 13を始める:環境構築からルーティング・Controller・Bladeまで」を参照してください。
Laravelの初期構成や生成コマンドはバージョンによって変わる可能性があります。実際のプロジェクトでは、composer.json、app/の内容、php artisan list makeの出力も確認してください。
appディレクトリの役割
Laravelのapp/には、アプリケーション固有の主要なPHPコードを置きます。ControllerやModelのほか、キューで実行するJob、メールを表すMailable、独自のバリデーションルールなども、基本的にはapp/の下へ配置します。
Laravelプロジェクトの主なディレクトリとの違いを整理すると、次のようになります。
| ディレクトリ | 主な役割 |
|---|---|
app/ |
Controller、Model、Jobなど、アプリケーション固有のPHPコード |
routes/ |
Web、コンソール、APIなどのルート定義 |
resources/ |
Blade、変換前のCSSやJavaScriptなど |
database/ |
Migration、Factory、Seeder、SQLiteファイルなど |
config/ |
アプリケーションやパッケージの設定 |
public/ |
Webサーバーから公開する入口と公開用ファイル |
各ディレクトリの詳しい役割は、Laravel 13.xのDirectory Structureで確認できます。
appディレクトリと名前空間の関係
Laravel 13の標準プロジェクトでは、composer.jsonに次のPSR-4オートロード設定があります。
{
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}
この設定は、App\で始まる名前空間をapp/へ対応させる、という意味です。例えば、ファイルパスと名前空間は次のように対応します。
app/Http/Controllers/DashboardController.php
App\Http\Controllers\DashboardController
app/Admin/Http/Controllers/DashboardController.php
App\Admin\Http\Controllers\DashboardController
ディレクトリを作るだけでなく、PHPファイルに記述する名前空間も同じ階層に合わせる必要があります。
通常のPSR-4構成では、既存のApp\とapp/の対応を変えずにクラスを追加するだけなら、クラスを追加するたびにcomposer dump-autoloadを実行する必要はありません。composer.jsonのオートロード設定を変更した場合や、本番環境で最適化したオートローダーを再生成する場合は、デプロイ手順に合わせて実行します。
Laravel 13の標準プロジェクトにある実際の設定は、Laravel公式のcomposer.jsonで確認できます。PSR-4の仕組みについては、ComposerのPSR-4に関する説明も参照してください。
Laravel 13の標準的なappディレクトリ
Laravel 13の新規プロジェクトでは、app/に主に次のディレクトリが用意されます。
app/
├─ Http/
├─ Models/
└─ Providers/
Http- HTTPリクエストを受け取るController、Middleware、Form Requestなどを置きます。
Models- Eloquent Modelを置きます。データベースのテーブルに対する取得、登録、更新、削除や、Model間の関連を表します。
Providers- サービスコンテナへの登録など、アプリケーションを起動するための処理を置きます。
Console、Jobs、Mail、Notifications、Policies、Rulesなどは、対応するArtisanコマンドを初めて実行したときに作成される場合があります。
php artisan make:command SampleCommand
php artisan make:job SampleJob
php artisan make:mail SampleMail
php artisan make:notification SampleNotification
php artisan make:policy SamplePolicy
php artisan make:rule SampleRule
公式ドキュメントに載っているディレクトリが手元に存在しなくても、それだけでLaravelのインストールに失敗しているとは限りません。必要な機能をまだ作成していない場合は、該当するディレクトリ自体がないことがあります。
app/Httpを基準に分ける構成
app/Httpは、HTTPリクエストを処理するコードを技術的な役割でまとめるLaravelの標準構成です。
app/
├─ Http/
│ ├─ Controllers/
│ ├─ Middleware/
│ └─ Requests/
├─ Models/
├─ Services/
└─ Actions/
ServicesとActionsはLaravelが必ず作成する標準ディレクトリではありません。アプリケーションの設計に合わせて追加する、プロジェクト側の規則です。
各クラスの役割は、次のように考えられます。
| 種類 | 主な役割 |
|---|---|
| Controller | リクエストを受け取り、必要な処理を呼び出してレスポンスを返す |
| Form Request | 入力値のバリデーションと、そのリクエストを実行できるかの判定をまとめる |
| Service | 複数のControllerや処理から利用する業務処理、外部サービス連携などをまとめる |
| Action | 「ユーザーを登録する」など、一つの操作やユースケースを一つのクラスへまとめる |
| Model | データの取得・保存、属性、キャスト、リレーションなどを表す |
ServiceやActionの分け方にLaravel共通の正解があるわけではありません。同じ処理をServiceとActionの両方へ重複させず、プロジェクト内で役割を決めて使います。
Form Requestは、次のコマンドで作成できます。
php artisan make:request Admin/UpdateSettingsRequest
Laravelの標準生成先はapp/Http/Requestsです。Form Requestの作成方法については、Laravel 13.xのForm Request Validationを参照してください。
管理画面のControllerだけを分ける
管理画面用のControllerが増えてきた程度であれば、まずはapp/Http/Controllers/Adminへまとめる方法が分かりやすいと思います。
app/
└─ Http/
└─ Controllers/
├─ Admin/
│ └─ DashboardController.php
└─ Controller.php
次のコマンドで、管理画面用のControllerを作成します。
cd D:\projects\laravel-example
php artisan make:controller Admin/DashboardController
作成先はapp/Http/Controllers/Admin/DashboardController.phpで、名前空間はApp\Http\Controllers\Adminになります。
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Response;
final class DashboardController extends Controller
{
public function index(): Response
{
return response('標準構成の管理画面');
}
}
LaravelのControllerは標準でapp/Http/Controllersへ作成されます。Admin/DashboardControllerのように階層を付けても、HTTP関連のコードをapp/Httpへ置くという標準の分類は維持できます。
app/Admin/Httpを基準に分ける構成
app/Admin/Httpは、Laravelが管理画面用として特別に用意しているディレクトリではありません。管理画面という機能領域を先に分け、その中へHTTP関連のコードを配置する独自構成です。
app/
└─ Admin/
├─ Actions/
├─ Http/
│ ├─ Controllers/
│ │ └─ DashboardController.php
│ └─ Requests/
├─ Models/
└─ Services/
この構成では、管理画面に関係するController、Form Request、Service、Action、ModelをAdminの下へまとめられます。管理画面のコードを一つのまとまりとして探しやすくなる一方で、Laravel標準の生成先とは異なるため、作成方法やチーム内の規則を決める必要があります。
今回は、PowerShellでディレクトリを作成し、Controllerを手動で用意します。
cd D:\projects\laravel-example
New-Item -ItemType Directory -Force app\Admin\Http\Controllers
app/Admin/Http/Controllers/DashboardController.phpを作成し、次のように記述します。
<?php
namespace App\Admin\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Response;
final class DashboardController extends Controller
{
public function index(): Response
{
return response('機能別構成の管理画面');
}
}
独自構成のControllerも、標準構成にあるApp\Http\Controllers\Controllerを継承できます。継承が不要であれば、通常のPHPクラスとして作成することもできます。
ServiceやActionを管理画面領域へ置く場合は、次のようにパスと名前空間を対応させます。
app/Admin/Services/DashboardService.php
App\Admin\Services\DashboardService
app/Admin/Actions/RebuildDashboardAction.php
App\Admin\Actions\RebuildDashboardAction
app/Admin/Models/AdminSetting.php
App\Admin\Models\AdminSetting
ModelをAdminの下へ置くかどうかは、そのデータが管理画面だけのものか、一般画面やAPIからも共通して使うものかで判断します。複数の機能から使うModelまで管理画面配下へ移すと、かえって依存関係が分かりにくくなることがあります。
ルートから二つのControllerを呼び出す
二つのControllerはクラス名が同じなので、routes/web.phpでは別名を付けて読み込みます。
<?php
use App\Admin\Http\Controllers\DashboardController as FeatureAdminDashboardController;
use App\Http\Controllers\Admin\DashboardController as StandardAdminDashboardController;
use Illuminate\Support\Facades\Route;
Route::get(
'/directory-example/standard',
[StandardAdminDashboardController::class, 'index']
);
Route::get(
'/directory-example/feature',
[FeatureAdminDashboardController::class, 'index']
);
ルートに登録されていることを確認します。
php artisan route:list
開発サーバーを起動し、次のURLへアクセスします。
php artisan serve
http://127.0.0.1:8000/directory-example/standard
http://127.0.0.1:8000/directory-example/feature
Laravelのルート定義ではControllerクラスを明示しているため、PSR-4で読み込める正しいファイルパスと名前空間になっていれば、標準構成と独自構成のどちらも呼び出せます。
二つの構成を比較する
| 観点 | app/Httpを基準にする |
app/Adminを基準にする |
|---|---|---|
| 分類の基準 | ControllerやModelなど技術的な役割 | 管理画面などの機能領域 |
| Laravel標準との近さ | 標準に近い | プロジェクト独自の構成 |
| Artisan | 標準の生成先を利用しやすい | 生成後の移動や手動作成が必要になる場合がある |
| 探しやすさ | 同じ種類のクラスをまとめて探しやすい | 管理画面に関係する複数種類のクラスをまとめて探しやすい |
| 向いている規模 | 学習用、小規模、標準構成で十分なアプリケーション | 管理画面が独立した大きな機能領域になっているアプリケーション |
| 導入時の注意 | 機能が増えると関連コードが複数ディレクトリへ分散する | 名前空間、生成方法、テスト配置などの規則が必要 |
管理画面用のControllerだけを分けたい場合は、app/Http/Controllers/Adminから始めるのがおすすめです。Laravelの標準構成やArtisanをそのまま利用でき、他の開発者も配置を予想しやすいためです。
Controllerだけでなく、Form Request、Service、Actionなども管理画面固有のものが増え、一つの機能としてまとめる利点が明確になった場合は、app/Adminを基準にした構成を検討できます。
どちらを選ぶ場合も、一つのプロジェクト内で分類方法を無秩序に混在させないことが大切です。独自構成を採用する場合は、どのクラスを機能領域の内側へ置き、どのクラスを共通領域へ置くかを決めておきます。
うまく動かない場合
Target class does not existになる
ファイルパス、名前空間、ルートのuse文が一致しているか確認します。
ファイル:
app/Admin/Http/Controllers/DashboardController.php
名前空間:
App\Admin\Http\Controllers
ルートのuse文:
use App\Admin\Http\Controllers\DashboardController;
Windowsでは動いても、Linuxへデプロイするとディレクトリ名やファイル名の大文字・小文字の違いで読み込めなくなる場合があります。Adminとadminのような表記も揃えてください。
DashboardControllerの名前が重複する
同じファイル内で同名のControllerを読み込む場合は、ルートの例のようにasで別名を付けます。クラス名だけでなく、完全修飾クラス名まで確認すると、どちらのControllerを呼び出しているか判断しやすくなります。
独自構成へ移動した後に参照できない
ファイルを移動した場合は、クラス自身の名前空間だけでなく、そのクラスを参照しているuse文やテストも修正します。
構文とルート定義は、次のコマンドで確認できます。
php -l app\Http\Controllers\Admin\DashboardController.php
php -l app\Admin\Http\Controllers\DashboardController.php
php artisan route:list
php artisan test
注意点
app/Adminというディレクトリ名にしても、管理画面の認証や認可は自動的に有効にならない。- ServiceやActionはLaravelが役割を固定している標準機能ではないため、プロジェクト内で責務を決める。
- 共通で利用するModelやServiceまで無理に管理画面配下へ入れない。
- 独自構成を採用する場合は、名前空間、Artisanによる生成方法、テストの配置をチーム内で共有する。
- ディレクトリ構成だけで処理を分離したつもりにならず、クラス間の依存関係も確認する。
まとめ
app/Httpは、HTTPリクエストを扱うクラスを技術的な役割でまとめるLaravelの標準構成です。一方、app/Admin/Httpは、管理画面という機能領域を先に分けるプロジェクト独自の構成です。
管理画面用のControllerを整理するだけなら、まずはapp/Http/Controllers/Adminで十分かと思います。標準構成を保ちながら、管理画面用のControllerを一か所へまとめられます。
管理画面固有のForm Request、Service、Actionなどが増え、機能単位でまとめる利点が大きくなった段階で、app/Adminを基準にした構成を検討するとよいでしょう。コードの探しやすさと運用ルールの負担を比べて選ぶことが大切です。
奈良市を拠点に、27年以上の経験を持つフリーランスWebエンジニア、阿部辰也です。
これまで、ECサイトのバックエンド開発や業務効率化システム、公共施設の予約システムなど、多彩なプロジェクトを手がけ、企業様や制作会社様のパートナーとして信頼を築いてまいりました。
【制作会社・企業様向けサポート】
Webシステムの開発やサイト改善でお困りの際は、どうぞお気軽にご相談ください。小さな疑問から大規模プロジェクトまで、最適なご提案を心を込めてさせていただきます。
ぜひ、プロフィールやWeb制作会社様向け業務案内、一般企業様向け業務案内もご覧くださいね。
Laravel Pintの使い方:PHPコードの書式を整えてCIで検査する
2026.09.15
Laravel Pintを使ってPHPコードの書式を整える方法を紹介します。ローカルでの自動修正、CIで書式違反だけを検査する--test、対象範囲の指定、pint.jsonの設定、Bladeファイルを扱う際の注意点を整理し、Pintを導入する判断基準も説明します。
GitHub ActionsでPHP・LaravelのCIを始める:テスト・Lint・ビルドを自動化するWorkflowの基本
2026.09.13
PHP・Laravelプロジェクトを対象に、GitHub ActionsのWorkflow、イベント、ジョブ、ステップの基本を説明します。Composerのテスト、npm ci、フロントエンドビルド、Laravel PintをCIへ組み込む方法に加え、featureブランチやPull Requestで実行される条件、失敗時のログ確認、Secrets・権限・Actionのバージョン管理についても整理します。
Laravel 13でArtisanコマンドを作成する:引数・オプション・dry-runの基本
2026.09.10
Laravel 13でArtisanコマンドを作成する方法を、引数・オプション・コンソール出力・終了コードの基本から解説します。日時指定した記事を定期的に公開するDB更新処理を例に、--dry-runで対象を確認してから安全に実行する方法や、スケジューラー・cronでの定期実行についても紹介します。
LaravelのFeature Testで開発用DBを初期化してしまった:Codex運用で学ぶテストDBの多層防御
2026.09.07
CodexにLaravelのFeature Test実行を依頼した際、テスト用DBではなくローカルの開発用DBへ接続した状態でRefreshDatabaseが実行され、データが失われる事故が発生しました。この記事では、PHPUnitのforce="true"による環境変数固定、DB_URLの無効化、config:clearのComposer Script化、Laravel起動後のDB接続先ガード、通常テストとIntegration Testの分離など、テストDBの誤接続を防ぐ多層防御を紹介します。