Laravel 6 ディレクトリ・ファイル構造

今最も熱いPHPのフレームワーク、[Laravel](https://laravel.com)
これから新たにLaravelを始める方も多いと思うので、`Laravel6.0`のディレクトリ構造について軽く解説したいと思います。

パートナーとして共に活動している[kahiro](https://qiita.com/kahirokunn)氏の[Laravel5.3ディレクトリ構造の解説](https://qiita.com/kahirokunn/items/ae587a20d2c5e39d5632) を参考にしています。

## プロジェクトルートディレクトリ一覧

プロジェクトのルートディレクトリで `ls -al` を実行したと時に表示されるディレクトリ及びファイルについて、[Readouble Laravel 6.0 ディレクトリ構造](https://readouble.com/laravel/6.0/ja/structure.html)の参考記事を引用しつつ解説します。

### ディレクトリ一覧

```
app
  Broadcasting *
  Console
  Events *
  Exceptions
  Http
    Controllers
    Middleware
    Requests
  Jobs *
  Listeners *
  Mail *
  Notifications *
  Policies *
  Providers
  Rules *
bootstrap
  cache
config
database
  migrations
  seeds
  factories
public
resources
  js
  lang
  sass
  views
routes
storage
  app
  framework
  logs
tests
vendor
```

- `*` はデフォルトでは存在しないディレクトリ

### ファイル一覧

```
artisan
readme.md
server.php
composer.json
composer.lock
phpunit.xml
package.json
.editorconfig
.env
.env.example
.gitattributes
.gitignore
.styleci.yml
webpack.mix.js
```

## イントロダクション

> Laravelのデフォルトアプリケーション構造はアプリケーションの大小にかかわらず、素晴らしいスタートを切ってもらえることを意図しています。アプリケーションは皆さんのお好みに応じ、自由に体系立ててください。クラスがComposerによりオートローディングできるならば、Laravelはクラスをどこに配置するか強制することはまずありません。

### modelsディレクトリはどこにある？

> Laravelを学習し始めるとき、多くの開発者は `models` ディレクトリが存在しないことに戸惑います。しかし、意図的にこのディレクトリを用意していません。多くの別々の人達にとって、その意味合いは様々なため、"models"という言葉の定義は曖昧であることに私達は気づきました。ある開発者たちはすべてのビジネスロジックを総称してアプリケーションの「モデル」と呼び、一方で別の人達はリレーショナルデータベースに関連するクラスを「モデル」として参照しています。

> このため、私達はEloquentモデルをデフォルトではappディレクトリ下へ設置することを選択し、開発者自分が選んだどこか別の場所へ設置してもらうことにしました。

デフォルトでは `app/User.php` とモデルクラスを配置します。
小規模開発であればこの配置でも良さそうです。

システムが大きくなると `app` ディレクトリ直下にモデルクラスがたくさんできることになるので、無難に `app/Models` ディレクトリを区切っても良さそうです。

モデルの置き場は設計によるので、自由に配置できるLaravelはとても便利ですね！

## appディレクトリ

> `app`ディレクトリは、アプリケーションのコアコードを配置します。このフォルダの詳細は、このあとに説明します。しかし、アプリケーションのほとんど全部のクラスは、このディレクトリの中に設定されることを覚えておいてください。

appディレクトリ内に業務で扱うクラスを配置します。
このディレクトリは重要なので、app配下のディレクトリについても説明します。

### app/Broadcastingディレクトリ

> このディレクトリはデフォルトで存在していません。`Broadcasting`ディレクトリは、アプリケーションの全ブロードキャストチャンネルクラスで構成します。これらのクラスは、`make:channel`コマンドで生成されます。最初にチャンネルを生成したときにこのディレクトリは作成されます。チャンネルについての詳細は、[イベントブロードキャスト](https://readouble.com/laravel/6.0/ja/broadcasting.html)のドキュメントで確認してください。

### app/Consoleディレクトリ

> `Console`ディレクトリは、アプリケーションの全カスタムArtisanコマンドで構成します。これらのコマンドクラスは`make:command`コマンドにより生成されます。コンソールカーネルもこのディレクトリ内にあり、カスタムArtisanコマンドや、[タスクのスケジュール](https://readouble.com/laravel/6.0/ja/scheduling.html)を登録します。

### app/Eventsディレクトリ

このディレクトリはデフォルトで存在していません。`event:generate`か`make:event` Artisanコマンド実行時に作成されます。`Events`ディレクトリは、[イベントクラス](https://readouble.com/laravel/6.0/ja/events.html)を設置する場所です。イベントは特定のアクションが起きたことをアプリケーションの別の部分に知らせるために使われ、柔軟性と分離性を提供しています。

### app/Exceptionsディレクトリ

> `Exceptions`ディレクトリはアプリケーションの例外ハンドラで構成します。また、アプリケーションから投げる例外を用意するにも適した場所でしょう。例外のログやレンダー方法をカスタマイズしたい場合は、このディレクトリの`Handler`クラスを修正してください。

### app/Httpディレクトリ

> `Http`ディレクトリはコントローラ、ミドルウェア、フォームリクエストを設置します。アプリケーションへのリクエストを処理するロジックは、ほぼ全てこのディレクトリ内に設置します。

#### app/Http/Controllersディレクトリ

> 全リクエストの処理をルートファイルのクロージャで定義するよりも、コントローラクラスにより組織立てたいと、皆さんも考えるでしょう。関連のあるHTTPリクエストの処理ロジックを一つのクラスへまとめ、グループ分けができます。コントローラはapp/Http/Controllersディレクトリ下に設置します。

- [Laravel 6.0 コントローラ](https://readouble.com/laravel/6.0/ja/controllers.html)

#### app/Http/Middlewareディレクトリ

> ミドルウェアはアプリケーションへ送信されたHTTPリクエストをフィルタリングする、便利なメカニズムを提供します。たとえば、アプリケーションのユーザーが認証されているかを確認するミドルウェアがLaravelに用意されています。ユーザーが認証されていなければ、このミドルウェアはユーザーをログインページへリダイレクトします。反対にそのユーザーが認証済みであれば、そのリクエストがアプリケーションのその先へ進むことを許可します。

> 認証の他にも多彩なタスクを実行するミドルウェアを書くことができます。たとえばCORSミドルウェアは、アプリケーションから返されるレスポンス全部に正しいヘッダを追加することに責任を持つでしょう。ログミドルウェアはアプリケーションにやってきたリクエスト全部をログすることに責任を負うでしょう。

> 認証やCSRF保護などLaravelには多くのミドルウェアが用意されています。これらのミドルウェアは全部、`app/Http/Middleware`ディレクトリに設置されています。

- [Laravel 6.0 ミドルウェア](https://readouble.com/laravel/6.0/ja/middleware.html)

#### app/Http/Requestsディレクトリ

> より複雑なバリデーションのシナリオでは、「フォームリクエスト」を生成したほうが良いでしょう。フォームリクエストは、バリデーションロジックを含んだカスタムリクエストクラスです。フォームリクエストクラスを作成するには、`make:request` Artisan CLIコマンドを使用します。

- [フォームリクエストバリデーション](https://readouble.com/laravel/6.0/ja/validation.html#form-request-validation)

### app/Jobsディレクトリ

> このディレクトリはデフォルトで存在していません。`make:job` Artisanコマンドを実行すると作成されます。`Jobs`ディレクトリはアプリケーションの[キュー投入可能なジョブ](https://readouble.com/laravel/6.0/ja/queues.html)を置いておく場所です。`Jobs`はアプリケーションによりキューに投入されるか、もしくは現在のリクエストサイクル中に同期的に実行されます。現在のリクエストサイクル中に同期的に実行するジョブは、[コマンドパターン](https://en.wikipedia.org/wiki/Command_pattern)を実装しているため、時に「コマンド」と呼ばれることがあります。

### app/Listenersディレクトリ

> このディレクトリはデフォルトで存在していません。`event:generate`か`make:listener` Artisanコマンドを実行すると、作成されます。`Listeners`ディレクトリには、[イベント](https://readouble.com/laravel/6.0/ja/events.html)を処理するクラスを設置します。イベントリスナはイベントインスタンスを受け取り、発行されたイベントへ対応するロジックを実行します。たとえば、`UserRegistered`（ユーザー登録）イベントは、`SendWelcomeEmail`（ウェルカムメール送信）リスナにより処理されることになるでしょう。

### app/Mailディレクトリ

> このディレクトリはデフォルトでは存在していません。`make:mail` Artisanコマンドを実行すると、作成されます。`Mail`ディレクトリは、アプリケーションから送信されるメールを表す全クラスで構成します。メールオブジェクトにより、`Mail::send`メソッドを使用して送られるメールを組み立てるロジックをすべて、１つのシンプルなクラスへカプセル化できます。

### app/Notificationsディレクトリ

> このディレクトリはデフォルトでは存在していません。`make:notification` Artisanコマンドを実行すると作成されます。`Notifications`ディレクトリは、アプリケーションから送られる全「業務上」の通知、たとえばアプリケーションの中でイベントが発生したことを知らせるシンプルな通知などで構成します。Laravelの通知機能は、メール、Slack、SMS、データベースへの保存などのように、様々なドライバに対する通知の送信を抽象化しています。

### app/Policiesディレクトリ

> このディレクトリはデフォルトでは存在していません。`make:policy` Artisanコマンドを実行すると、作成されます。`Policies`ディレクトリにはアプリケーションの認可ポリシークラスを設置します。ポリシーは、リソースに対し指定したアクションをユーザーが実行できるかを決定します。詳細は、[認可のドキュメント](https://readouble.com/laravel/6.0/ja/authorization.html)をご覧ください。

### app/Providersディレクトリ

> `Providers`ディレクトリは、アプリケーションの全[サービスプロバイダ](https://readouble.com/laravel/6.0/ja/providers.html)により構成します。サービスプロバイダは、サービスをコンテナと結合、イベントの登録、もしくはアプリケーションへやってくるリクエストを処理するために必要な用意をするタスクを実行するなど、アプリケーションの事前準備を行います。

> インストール直後のアプリケーションでも、このディレクトリは多くのプロパイダーを含んでいます。必要に応じて、自分のプロバイダを自由に追加してください。

### app/Rulesディレクトリ

> このディレクトリは、デフォルトでは存在していません。`make:rule` Artisanコマンドを実行すると、作成されます。`Rules`ディレクトリは、アプリケーションで使用するバリデーションルールオブジェクトで構成します。ルールは複雑なバリデーションロジックをシンプルなオブジェクトへカプセル化するために使用します。詳細は、[バリデーションのドキュメント](https://readouble.com/laravel/6.0/ja/validation.html)で確認してください。

## bootstrapディレクトリ

> `bootstrap`フォルダは、フレームワークの初期処理を行うapp.phpファイルを含んでいます。その中の`bootstrap/cache`ディレクトリは、初期処理のパフォーマンスを最適化するため、フレームワークが生成するルートやサービスのキャッシュファイルが保存されるフォルダです。

この`bootstrap`ディレクトリに自分でコードを追加したり、編集したりといったことはまずないです。

## configディレクトリ

> `config`ディレクトリは名前が示す通り、アプリケーションの全設定ファイルが設置されています。全ファイルに目を通し、設定可能なオプションに慣れ親しんでおくのは良い考えでしょう。

`config` で設定している値は `.env` ファイルで上書きできる項目もあります。
ここで設定している値は、`config('ファイル名.キー値')`とアクセスできます。

また、`config/*.php` と配置されている設定ファイル群は配列を返すだけなので。
新たに自身で新しくファイルを作れば、同様に`config`関数でアクセスできます。

## databaseディレクトリ

> `database`フォルダはデータベースのマイグレーションとモデルファクトリ、初期値設定（シーディング）を配置します。ご希望であれば、このファイルをSQLiteデータベースの設置場所としても利用できます。

### database/migrationsディレクトリ

> マイグレーションとはデータベースのバージョンコントロールのような機能です。アプリケーションデータベースのスキーマの更新をチームで簡単に共有できるようにしてくれます。マイグレーションは基本的にLaravelのスキーマビルダとペアで使い、アプリケーションのデータベーススキーマの作成を楽にしてくれます。もしあなたが今まで、チームメイトに彼らのローカルデータベーススキーマに手作業でカラムを追加するよう依頼したことがあるなら、データベースマイグレーションは、そうした問題を解決してくれます。

- データベースのテーブル構成のバージョン管理ツール
- マイグレーションクラスを配置する
  - up, down は整合性に注意して書く
- [Laravel 6.0 データベース：マイグレーション](https://readouble.com/laravel/6.0/ja/migrations.html)

### database/seedsディレクトリ

> シーダ（初期値設定）クラスを使用し、テストデーターをデーターベースに設定するシンプルな方法もLaravelには備わっています。全シーダクラスは`database/seeds`に保存します。シーダクラスには好きな名前を付けられます。しかし`UsersTableSeeder`などのような分かりやすい規則に従ったほうが良いでしょう。デフォルトとして`DatabaseSeeder`クラスが定義されています。このクラスから`call`メソッドを使い他の初期値設定クラスを呼び出すことで、シーディングの順番をコントロールできます。

- [Laravel 6.0 データベース：シーディング](https://readouble.com/laravel/6.0/ja/seeding.html)

### database/factoriesディレクトリ

> テスト実行前に、何件かのレコードをデータベースに挿入する必要があります。こうしたテストデータを作る時に、手動でそれぞれのカラムへ値を指定する代わりに、Laravelではモデルファクトリを使用し、Eloquentモデルの各属性にデフォルト値を設定できます。

- [Laravel 6.0 データベースのテスト
 ファクトリの記述](https://readouble.com/laravel/6.0/ja/database-testing.html#writing-factories)
- [Laravel 6.0 データベース：シーディング モデルファクトリの利用](https://readouble.com/laravel/6.0/ja/seeding.html#using-model-factories)

## publicディレクトリ

> `public`ディレクトリには、アプリケーションへの全リクエストの入り口となり、オートローディングを設定する`index.php`ファイルがあります。また、このディレクトリにはアセット（画像、JavaScript、CSSなど）を配置します。

## resourcesディレクトリ

> `resources`ディレクトリはビューやアセットの元ファイル（LESS、SASS、JavaScript）で構成されています。また、すべての言語ファイルも配置します。

## routesディレクトリ

> ディレクトリはアプリケーションの全ルート定義により構成されています。デフォルトでは、`web.php`、`api.php`、`console.php`、`channels.php`ファイルが含まれています。

> `web.php`ファイルは、`RouteServiceProvider`の`web`ミドルウェアグループに属するルートで構成します。このミドルウェアは、セッションステート、CSRF保護、クッキーの暗号化機能を提供しています。もしアプリケーションがステートレスではなく、RESTフルなAPIを提供しないのであれば、すべてのルートは`web.php`ファイルの中で定義されることになるでしょう。

> `api.php`ファイルは、`RouteServiceProvider`の`api`ミドルウェアグループに属するルートで構成します。このミドルウェアはアクセス回数制限を提供しています。このファイル中で定義されるルートは、ステートレスであることを意図しています。つまり、これらのルートを通るアプリケーションに対するリクエストは、セッションステートにアクセスする必要がないように、トークンを使って認証されることを意図しています。

> `console.php`ファイルは、クロージャベースの全コンソールコマンドを定義する場所です。それぞれのコマンドのIOメソッドと連携するシンプルなアプローチを提供するコマンドインスタンスと、各クロージャは結合します。厳密に言えば、このファイルはHTTPルートは定義していないのですが、コンソールベースのエントリポイントを定義しているという点で、ルート定義なのです。

> `channels.php`ファイルはアプリケーションでサポートする、全ブロードキャストチャンネルを登録する場所です。

## storageディレクトリ

> `storage`ディレクトリにはコンパイルされたBladeテンプレート、ファイルベースのセッション、ファイルキャッシュなど、フレームワークにより生成されるファイルが保存されます。このフォルダは`app`、`framework`、`logs`ディレクトリに分かれています。`app`ディレクトリはアプリケーションにより生成されるファイルを保存するために利用します。`framework`ディレクトリはフレームワークが生成するファイルやキャッシュに利用されます。最後の`logs`ディレクトリはアプリケーションのログファイルが保存されます。

> `storage/app/public`ディレクトリにはプロファイルのアバターなどのようなユーザーにより生成され、外部からアクセスされるファイルが保存されます。`public/storage`がこのディレクトリを指すように、シンボリックリンクを張る必要があります。リンクは、`php artisan storage:link`コマンドを使い生成できます。

## testsディレクトリ

> `tests`ディレクトリには皆さんの自動テストを配置します。サンプルの[PHPUnit](https://phpunit.de)テストが最初に含まれています。各テストクラスはサフィックスとして`Test`を付ける必要があります。テストは`phpunit`か、`php vendor/bin/phpunit`コマンドにより実行できます。

## vendorディレクトリ

> `vendor`ディレクトリには、[Composer](https://getcomposer.org)による依存パッケージが配置されます。

## artisanファイル

```
$ php artisan xxx
```

Laravelのartisanコマンドを叩く時に実行されているファイルです。

- https://readouble.com/laravel/6.0/ja/artisan.html

## readme.mdファイル

READMEというのは、GitHub/Bitbucket等で公開されるソフトウェア（リポジトリ）の説明書きのことになります。

プロジェクトの概要説明から開発環境の立ち上げ、貢献方法への案内などを簡潔にまとめます。

`.md` 拡張子は文章を記述するための記法（マークアップ言語）です。
`readme.md`, `README.md` ファイル名は大文字でも小文字でもどちらでも構いません。
お好みです。

- [Markdown記法 サンプル集](https://qiita.com/tbpgr/items/989c6badefff69377da7)
- [わかりやすい README 駆動開発](https://qiita.com/b4b4r07/items/c80d53db9a0fd59086ec)
- [README のファイル名が大文字である理由](https://blog.clock-up.jp/entry/2014/05/08/readme-filename)

## server.phpファイル

```
$ php artisan serve
```

ビルトインサーバー起動時に使用されます。

## composer.jsonファイル

`composer.json`はPHPのパッケージ管理ツール「[Composer](https://getcomposer.org)」の設定ファイルで、インストールしたいパッケージをJSON形式で管理します。

また、オートローディングやスクリプトなどの設定もできます。

- `composer install`
  - `composer.lock` を参照します。
  - `composer.lock` がない場合、`composer.json`を参照します。
- `composer update`
  - `composer.json` を参照します。

## composer.lockファイル(ロックファイル)

`composer.lock`は`composer.json`に記述したパッケージをインストールしたあとに、実際にインストールしたパッケージのバージョンのリストを`composer.lock`に書き込みます。

ロックファイルにより、プロジェクトメンバーは同一のバージョンで開発が行えます。

## phpunit.xmlファイル

`phpunit.xml`はPHP用のテスティングフレームワーク「[PHPUnit](https://phpunit.de)」の設定ファイルです。

## package.jsonファイル

[Node.js](https://nodejs.org/ja)のパッケージ管理設定ファイルです。
パッケージ管理ツールとしては[npm](https://www.npmjs.com)か[yarn](https://yarnpkg.com/lang/ja)が使用されます。

`npm install`をすると`node_modules`というディレクトリが作成され、`package.json`に定義されたパッケージがインストールされます。
実際にインストールしたバージョンのリストを`package-lock.json`というロックファイルに作成します。

`yarn install`をすると`node_modules`というディレクトリが作成され、`package.json`に定義されたパッケージがインストールされます。
実際にインストールしたバージョンのリストを`yarn.lock`というロックファイルに作成します。

`npm`, `yarn`どちらも人気なパッケージ管理ツールだと思いますが、使用する場合はどちらか一方に統一して使用しましょう。

## .editorconfigファイル

[EditorConfig](https://editorconfig.org)は、さまざまなエディターやIDEで一貫したコーディングスタイルを定義します。

文字コードや改行コード、インデントの数をファイル形式に毎に設定できます。

## .envファイル

`.env` は環境設定ファイルです。
開発環境や本番環境で異なる設定を管理するファイルです。
基本的にGit管理対象外にするファイルです。
データベースの接続情報など機密性の高い情報を扱うため注意が必要です。

補足ですが、
`.env`ファイルにあるすべての変数は、サーバレベルやシステムレベルで定義されている、外部の環境変数によってオーバーライドできます。

- [Laravel 6.0 設定
](https://readouble.com/laravel/6.0/ja/configuration.html)
- [phpdotenv](https://github.com/vlucas/phpdotenv)

## .env.exampleファイル

環境設定ファイルのサンプルファイルです。
プレースホルダーとして開発環境用の値を設定しておけば、チームメンバーはスムーズに開発環境の構築が行えます。

さらに`.env.testing`ファイルを作成できます。このファイルはPHPUnitテスト実行時やArtisanコマンドへ`--env=testing`オプションを指定した場合に、`.env`ファイルをオーバーライドします。

## .gitattributesファイル

`.gitattributes`ファイルはGitの属性設定ファイルです。
あまり意識しなくていいファイルだと思います。

- [gitattributes](https://git-scm.com/docs/gitattributes)

## .gitignoreファイル

`.gitignore`ファイルはGitの管理対象外設定ファイルです。
`.env` や `vendor` 等Gitで管理しないファイルやディレクトリを設定します。

- [[Git] .gitignoreの仕様詳解](https://qiita.com/anqooqie/items/110957797b3d5280c44f)

## .styleci.ymlファイル

`.styleci.yml`ファイルはコードチェックサービス「[StyleCI](https://docs.styleci.io)」の設定ファイルです。

StyleCIはLaravel公式が利用しているサービスで、PHPやcss、jsのフォーマットをチェックし、自動で整形してくれるサービスです。

GitHub、GitLab、Bitbacketと連携ができ、各種ホスティングサービスにpushすると、自動的にチェックが行われます。プルリク単位やコード全体に対してチェックできます。

- [LaravelでコードチェックサービスStyleCIを利用してみる](https://i-yusuke.com/entry/styleci-laravel)

## webpack.mix.jsファイル

`webpack.mix.js`ファイルはLaravel Mixの設定ファイルです。
webpackの設定をシンプルなメソッドチェーンで定義できるwebpackのラッパーライブラリです。

- [webpack](https://webpack.js.org)
- [mix](https://readouble.com/laravel/6.0/ja/mix.html)
- [webpack.mix.js って何？](https://qiita.com/masash49/items/fb64805fcebd68f3b19f)

## リンク

- [Laravel 6.0 Directory Structure](https://laravel.com/docs/6.0/structure)
- [Readouble Laravel 6.0 ディレクトリ構造](https://readouble.com/laravel/6.0/ja/structure.html)
- [GitHub laravel/framework](https://github.com/laravel/framework)
- [GitHub laravel/laravel](https://github.com/laravel/laravel)