Laravelのディレクトリ構造について学ぶ


Laravelのドキュメントの `Directory Structure` について読んでみました。
（一部についてはまだ読めていません）

https://laravel.com/docs/5.4/structure

#ディレクトリ（Root Directory）の構成

- app
- bootstrap
- config
- database
- **public**
- resources
- routes
- storage
- tests
- vendor

#Laravelのディレクトリ構造の特徴

デフォルトのLaravelのアプリケーション構造は大きくも小さくもできるようになっている。
もちろん、そのまま使うのではなく各々が好き勝手カスタマイズすることだってOK。

Laravelは **Composerがautoloadクラスさえ読めれば** どこにクラスを配置したってかまわないさ、という感じだそうです。

##Models Directoryはないの？

開発者の中には「なぜ `models` ディレクトリがないのか？」という人もいるかもしれない。
これはLaravelを開発するときに作り忘れたのではなく、意図的にそうしたらしいです。

というのも、 `models` という言葉の定義は人によって全然定義が違うことが理由らしい。
ある人は `models` を「ビジネスロジック全て」と言い、ある人は `models` を「データベースに関連するクラス」と言う、といったように。

「そんなんだったら `models` のディレクトリ作ったらややこしくない？」ということで
`Models Directory` を作らず、代わりにデフォルトでは `app directory` に `Eloquent` を置くことにしたそうです。

#各ディレクトリの役割

## `app`

大体想像はつくかもしれませんが、アプリケーションのコアとなるコードを含むディレクトリです。
アプリケーション内のクラスのほとんどはこの中に設置される感じ。
このディレクトリは重要なのでもう少し詳しく説明します。

## `bootstrap`

フレームワークの初期化を行い、autoloadingを設定するファイルをおく。
また、フレームワークが作り出すキャッシュファイルを貯めたりもする。

## `config`

名前の通り、アプリケーションの設定ファイルをおくディレクトリ。
「ここを読んでおくと"オプションで何が使えるのか"がよくわかると思うよ！」だそう。

## `database`

データベースのマイグレーションやシードをおくディレクトリ。
SQLiteを使いたい時にも利用できる。

## `public`

アプリケーションに送られる、全てのリクエストのエントリーポイント（最初に実行される）となる`index.php` ファイルがあるところ。
ここには他に画像、JS、CSSといったものを置いたりする。

## `resources`

コンパイル前のLESS、SASS、JS、viewといったものを置くところ。
また、言語ファイルを置いたりもする。

![スクリーンショット 2017-04-26 10.30.36.png](https://qiita-image-store.s3.amazonaws.com/0/109241/5915d6be-3978-0d7a-e3f8-773ca43066d8.png "スクリーンショット 2017-04-26 10.30.36.png")

## `routes`

アプリケーションの全てのルートを定義するディレクトリ。
デフォルトでは `web.php` `api.php` `console.php` `channels.php` といったルートファイルを用意してある。

### `web.php` ・ `api.php`

`web.php` はセッション、CSRF対策、cookieの暗号化といった機能を提供する `web` ミドルウェアを経由する。
stateless,RESTful APIといったアプリケーションを作るならこのファイルだけでルートを定義できる感じ。

一方 `api.php` は `api` ミドルウェアを経由し、ステートレス（状態を保持しないシステムやプログラムのことらしい）なルートである。
なのでトークンを経由する認証や、セッションにアクセスする必要のないものがここを通る。

どちらも `RouteServiceProvider` でミドルウェアが指定されている↓

![スクリーンショット 2017-04-25 22.54.11.png](https://qiita-image-store.s3.amazonaws.com/0/109241/de1d0a29-ba3e-acab-db06-646c47b2797c.png "スクリーンショット 2017-04-25 22.54.11.png")

### `console.php`

普通のRouteっぽく、インラインでコマンドが作れるファイル。
下のコードだと `php artisan inspire` で実行できる。

![スクリーンショット 2017-04-25 23.12.42.png](https://qiita-image-store.s3.amazonaws.com/0/109241/5a15bdf9-9bbc-725b-1ed3-f39b758c7f77.png "スクリーンショット 2017-04-25 23.12.42.png")

### `channels.php`

ブロードキャストするイベントを登録するファイル。

## `storage`

Bladeテンプレートをコンパイルしたものやセッションのファイル、キャッシュファイル、その他フレームワークが作り出したファイルなんかが置かれる。
ディレクトリは `app` `framework` `logs` の３つに分かれている。

![スクリーンショット 2017-04-26 10.19.56.png](https://qiita-image-store.s3.amazonaws.com/0/109241/62f8d407-e45f-1ba0-b1d4-694766c04196.png "スクリーンショット 2017-04-26 10.19.56.png")

`app` にはアプリケーション内でつくったファイルを、`framework` にはフレームワークが作ったファイルやキャッシュを、`logs` にはアプリケーションのログを貯める。

`storage/app/public` についてはユーザーのプロフィールアバターといったいろんなとこで使いたくなるようなファイルを置く場所。
https://laracasts.com/series/whats-new-in-laravel-5-3/episodes/12
のようにLaravel 5.3からアップロードファイルの格納が簡単にできるようになり、その置き場所となっている。

## `tests`

`PHPUnit` みたいな自動テストを置くためのディレクトリ。
全てのクラスには `Test` を接尾辞をつけないといけない。

テストを走らせるには `phpunit`コマンドか `php vendor/bin/phpunit`かを使う。

## `vendor`

`Composer` の依存内容をおくところ。

# `app` についてさらに詳しく

上記のようにいろんなディレクトリがありますが、基本的に大体のものは `app` ディレクトリに置くと思っていいです。

`app` ディレクトリ以下のnamespaceは `App` 、デフォルトで用意されているフォルダは `Console` `Exceptions` `Http` `Providers` です。

![スクリーンショット 2017-04-26 14.39.52.png](https://qiita-image-store.s3.amazonaws.com/0/109241/d1d31697-24a6-b5d8-ba81-79633dd1f57b.png "スクリーンショット 2017-04-26 14.39.52.png")

## `Console`

自分で Artisan commandsをつくれるところ。

```
php artisan make:commands test
```

とすれば、コマンド用ファイルが作られる。
`handle()` に処理をかけばいい感じ。

![スクリーンショット 2017-04-26 15.18.44.png](https://qiita-image-store.s3.amazonaws.com/0/109241/a003483d-60ef-fe42-cbcd-63116f37c89c.png "スクリーンショット 2017-04-26 15.18.44.png")

作ったコマンドは `Kernel.php` に登録しておく。

![スクリーンショット 2017-04-26 15.20.16.png](https://qiita-image-store.s3.amazonaws.com/0/109241/1e69767e-c885-2b42-aaae-3d1191c967c9.png "スクリーンショット 2017-04-26 15.20.16.png")

## `Exceptions`

例外処理を置いておくところ。
「どうやってログを吐くか、レンダリングをするか」といったことをカスタマイズしたいのであればこのクラスの `Handler` クラスをいじればいいとのこと。

## `Http`

コントローラ、ミドルウェア、フォームリクエストなどをおくところ。
アプリケーションへのリクエスト処理に関するほとんどのロジックがこのディレクトリに含まれる。

## `Providers`

アプリケーションの中の全てのサービスプロバイダがここにくる。
サービスコンテナ、登録したイベント、リクエストに対するタスクをbindingして実行してくれる、的な？（よくわからない）

##Artisan commandsで作ればできるもの

実はArtisan commandsを使えば、このディレクトリ内には他にもいろいろつくることができます。

###Artisan commandsの一覧がみたいとき

`php artisan list make` で一覧が表示できる。

![スクリーンショット 2017-04-26 14.57.37.png](https://qiita-image-store.s3.amazonaws.com/0/109241/a89f0b0c-2d43-58c7-2fe0-ca3729e27618.png "スクリーンショット 2017-04-26 14.57.37.png")

## `Events`

「アプリケーションに何かアクションが起きた時に、イベントを発生させたい！」といったときとかに使えるもの。（多分）

### 作り方

```
php artisan event:generate
```

もしくは

```
php artisan make:event Hoge
```

でファイルを作成。

![スクリーンショット 2017-04-26 15.47.39.png](https://qiita-image-store.s3.amazonaws.com/0/109241/fee31901-bd34-39fc-db4f-48c95e67fbe3.png "スクリーンショット 2017-04-26 15.47.39.png")

`make:event Hoge` としたときは `Hoge` ファイルができ、
> Event created successfully.


`event:generate` したときは
> Events and listeners generated successfully!

と文章が表示される。
下のコマンドだと次の `Listneners` ディレクトリが一緒につくられるっぽい。

## `Listeners`

イベントをハンドリングするクラス。

`Listeners` が `Event` からインスタンスを受け取り、イベントが発火したときのレスポンスとしてロジックを実行する、みたいな感じ？

（ただ、「例えば」として書いてある以下の文章がそれだと合わないので解釈が間違っているかもしれません）

> For example, a `UserRegistered` event might be handled by a `SendWelcomeEmail` listener.

### 作り方

`Events` のときの `php artisan event:generate` で一緒に作ってしまうか、次のコマンドで単独作成もできる。

```
php artisan make:listener
```

ただ `--event` というオプションが必要みたいで、なんかうまくいかなかった（他にも何かいるっぽい）。
また今度調べて見る。

## `Jobs`

このフォルダには順番に実行してほしいjobを書く感じ？

### 作り方

```
php artisan make:job
```

## `Mail`

メールを送るとき用のクラスをおくところ。

### 作り方

```
php artisan make:mail
```

でMailableインターフェースをそなえたクラスができる。

## `Notifications`

5.3からできるようになった `Notifications` のクラスをおくところ。
`Notifications` によりメール、Slackなどのチャンネルに通知するAPIを簡単に実装できるようになった。

### 作り方

```
php artisan make: notification
```

## `Policies`

「この人はその処理を実行してもよいのか」とかを書くクラスが置かれる。

### 作り方

```
php artisan make:policy
```

# ディレクトリ構造を学んでみて、役割分担がちゃんとあることを知った

今までは正直、自分のよく使うところしか目を通していませんでしたが（`app/Http`や`resources/views`とか）
今回基本的なディレクトリ構造をさらっとでも目を通したことでLaravelの便利な機能や「どこに何を書けばいいのか」について少しわかったかなぁと思います。

ただできることがかなり多い反面、小さめのプロジェクトに使うのにはもったいないような気がします。
おそらくそういう場合にいいのがLumenなのかなぁと。
https://lumen.laravel.com/
なので自分で何か作ってみたくなったときはLumenを使ってやってみたいな、とも思いました。

とっても勉強になりました。