Laravel MVCの処理の流れ（簡単な実装例をもとに解説）

# 対象
- MVCって何？という人
- MVCという言葉は知ってるけど，実装がいまいちわからない人
# Laravelのバージョン
```
$ php artisan -V
Laravel Framework 9.26.1
```
# MVCの導入
まずは，MVCをそもそも聞いたことがない人のために，導入としてMVCを簡単に説明したいと思います．

この記事では，こちらの図を使って説明していきます．
![MVC構造.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884121/735c1de8-6204-a01c-3357-37590ad7494f.jpeg)

MVCとは，UI（ユーザーインタフェース）を持つソフトウェアに適用されるアーキテクチャ（構造）の一種で，M（モデル），V（ビュー），C（コントローラ）に処理を分割して，ソフトウェアの内部データをユーザーが直接参照・編集できる情報から分離する構造のことを言います．

わかりづらいですね・・・
ということで，事前にいくつかの疑問を解消したうえで，実装していこうと思います．

- UIって何？
ユーザーが直接参照・編集できる部分のことです（Webページなど）．
- MVCのそれぞれの役割は？
`M（Model:モデル）`
内部データ（サーバ内のデータ）にアクセスし，データの抽出・挿入などを行います．
`V（View:ビュー）`
渡されたデータをもとに，ユーザー側にUI（Webページなど）を提供します．
`C（Controller:コントローラ）`
モデルとビューに指示を送ります．
モデルへの指示：「どのデータにどのような操作をするのか」を指示する
ビューへの指示：「どのデータをどのビューへ渡し，表示するのか」を指示する

- なぜ役割を分割するの？
ソフトウェアの規模が大きくなっても，保守性と可読性を高く保つためです．ここについては実装を見ていくとわかってくると思います．

# 簡単な実装例を通して考える
ここからは実際に簡単な実装例を通して，MVCの流れを見ていきます．
以下のように，投稿（Post）のタイトル（title）と本文（body）をWebページに一覧表示させます．
```:完成ページ
title1
body1

title2
body2

title3
body3

...(省略)...
```
また，Postテーブルは以下のような構成になっています（詳細は省略しています）．
```:Postテーブル
id・・・・・・・・投稿ID(PK)
title・・・・・・ 投稿タイトル
body・・・・・・・投稿本文
crated_at・・・・ 作成日時
updated_at・・・・更新日時
```
## ルーティング（web.php）
![MVC構造.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884121/735c1de8-6204-a01c-3357-37590ad7494f.jpeg)

まずはルーティングから実装していきます．
`ルーティングとは，UI（Webページ）で受け取ったリクエスト（URLなど）に対してどのような処理を行うかを定義する部分`のことです．
Laravelでは`web.php`というファイルにその定義を記述します．
```php:/routes/web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

Route::get('/index', [PostController::class, 'index']);
```
ここで`Route::get('/index', [PostController::class, 'index']);`は，上部で`use`している`Route`を用いて受け取った，`/index`というURLの`get`メソッドのリクエスト（図中➀）に対して，上部で`use`している`PostController`クラス内の，`index`メソッドを実行する（図中➁）ということを定義しています．
## Controller
![MVC構造.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884121/735c1de8-6204-a01c-3357-37590ad7494f.jpeg)

ということで，次は呼び出される`PostController`クラスと，その中にある`index`メソッドを定義しましょう．
```php:/app/Http/Controllers/PostController.php
<?php

namespace App\Http\Controllers;

use App\Models\Post;

class PostController extends Controller
{
    public function index(Post $post)
    {
        return view('posts/index')->with(['posts' => $post->getOrderBy()]);
    }
}
```
こちらも一つずつ説明していきます．
まず，`namespace`についてですが，なぜこれを記述する必要があると思いますか？

・・・

先ほど`web.php`内で，`use App\Http\Controllers\PostController;`という記述があったと思います．これは`App\Http\Controllers`というディレクトリ構造の中にある`PostController`クラスをこのファイルで利用しますという宣言です．

ここで，人間であればエディターからディレクトリ構造を確認し，`App\Http\Controllers`というディレクトリ構造の中にある`PostController.php`を簡単に見つけることができ，その中に`PostController`クラスがあることを突き止めることが出来ます．

ただ，これと同じことをコンピュータにやらせようと思ったら，あなたならどうするでしょうか？

・・・

このアプローチの一つが`namespace`です．日本語だと名前空間とも呼ばれますが，ファイル内に自身のディレクトリの相対位置を記述しておくことで，コンピュータはファイルを見つけることが出来るようになります．

続いて，`Post`クラスを`use`しています．これは後ほど実装するモデルに処理をお願いするための宣言です．

その後，`Controller`クラスを`extends`（継承）した`PostController`クラスを定義します．この`extends`をすることで，Laravelが用意してくれた`Controller`クラスのメソッドを継承したうえで`PostController`クラスを拡張していくことが出来ます．

ここからやっと`index`メソッドの説明に入ります．
まず引数に注目しましょう．`(Post $post)`となっています．これは上部で`use`した`Post`クラスを`$post`にインスタンス化しています．

ここで，インスタンス化とは「実際にたい焼きをつくること」だと考えてください．
クラスとは「たい焼き」を作る型です．たい焼きそのものではないので，中にあんこをいれたり，カスタードを入れたりすることはできません．
実際に食べる（使用する）ためには，その型を使って「実際にたい焼きをつくること」が必要です．これがインスタンス化の意味するところになります．

ということで，返り値（`return`）の部分で実際に使用していきます．
まずは，「どのビューを表示させるのか」を定義しています．今回の場合だと，`/resources/views/posts`内にある`index.blade.php`を表示させています（図中➂）．

続いて，`with`以降の部分で「どのデータを渡すのか」を定義しています．今回の場合だと，`$post`の`getOrderBy`メソッド（図中➃）を使用した結果を`posts`という名前をつけて，`index.blade.php`に渡しています．

この`getOrderBy`メソッドとは何でしょう？
これは，次のモデルで定義することになります．

## Model
![MVC構造.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884121/735c1de8-6204-a01c-3357-37590ad7494f.jpeg)

ということで，`index`メソッド内で呼び出された`getOrderBy`メソッドを実装していきましょう．
```php:/app/Models/Post.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{    
    public function getOrderBy()
    {
        return $this->orderBy('updated_at', 'DESC')->get();
    }
}
```
ここでの説明は，これまで説明してきたものと被る部分があるので，すこし省略して説明します．まず，`namespace`を定義し，`Model`クラスを`use`します．
そして，その`Model`クラスを継承した，`Post`クラスを定義し，その中で，`getOrderBy`メソッドを定義しています．

まず，`$this`について説明したいと思います．これは「このメソッドが所属するクラス（親クラス）のインスタンス」を表します．
つまり，この場合はPostクラスのインスタンス，`PostController`内で言うところの`$post`にあたります．

そして，その中にある，`orderBy`メソッドと，`get`メソッドを順に使用しています（図中➄）．
この`orderBy`メソッドと，`get`メソッドは`Model`クラスに標準装備されているメソッドで，`Post`クラスが`Model`クラスを`extends`しているため，使用することが出来ます．

ここで，`orderBy('updated_at', 'DESC')`は`$this`内のデータを更新日時（`updated_at`）を基準に，降順（`DESC`）に並び替えるメソッドです．
そして，`get`メソッドはそのデータを抽出するメソッドです．

つまり，返り値の`$this`には，更新日時を基準に，降順に並び替えられたPostモデル内のデータが全て格納されていることになります．

## View
![MVC構造.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884121/735c1de8-6204-a01c-3357-37590ad7494f.jpeg)

最後は`index`メソッドの返り値で指定されていた`index.blade.php`を実装していきましょう．
```html:/resources/views/posts/index.blade.php
<!DOCTYPE html> 
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        ...(省略)...
    </head>
    <body>
        <div class='posts'>
            @foreach ($posts as $post)
            <div class='post'>
                <h1 class='title'>{{ $post->title }}</h1>
                <p class='body'>{{ $post->body }}</p>
            </div>
            @endforeach
        </div>
    </body>
</html>
```
ここで注目すべきは`posts`というクラス名が付けられた`div`タグの中身です．`@foreach ($posts as $post)`の部分で，`PostController`で渡した`posts`を`$posts`として使用しているのが分かると思います（※bladeファイル内では渡された名前（`posts`）に`$`をつけることで取り扱えるようになります）．
`$posts`は`foreach`ディレクティブというBladeファイルの機能により`$post`に一つずつ順番に格納され，`post`というクラス名が付けられた`div`タグの中身が`$posts`内の投稿の個数分だけ繰り返されます（今回はメインのトピックではないのでこれ以上の説明は省略します）．

ここまでの実装により，最初に示したWebページを表示することが出来ます．

# まとめ（MVCとは）
![MVC構造.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884121/735c1de8-6204-a01c-3357-37590ad7494f.jpeg)

以上の実装を通して，なぜこのようなアーキテクチャを採用しているかが，なんとなくわかっていただけたでしょうか？

この記事の実装はごく簡単なものでしたが，規模が大きくなるにつれて，コードの量は増えていきます．その際に，これまでのMVCの役割を全て一つのファイルが担っていたとしたらどうでしょう？

`とても読みづらいし，メンテナンスなんて無理`ですよね．

また，ユーザーが簡単にサーバのデータにアクセスできてしまうと，`セキュリティ面で危険`です．

以上のような理由から，UIを持つソフトウェア開発では，MVCの役割分担を守って実装していきましょう．

ただ，このMVC構造が最善の手段というわけではありません．人によってこだわりがあったり，そもそもMVC以外のアーキテクチャも存在します．また，今後よりよいアーキテクチャが開発される可能性もあります．

そのため，`まずは基本を守ったうえで，様々な人・本・経験から学んで，自分自身で本当に良い実装というものを考え続けていく`のが最も大切だと思います．