Help us understand the problem. What is going on with this article?

Laravel5.5こと始め 〜3. MVCとルーティングの説明〜

More than 1 year has passed since last update.

内容

以下の順番にまとめます。
1. MacへのXAMPP+Laravelインストール
2. ユーザログイン機能の追加
3. MVCとルーティングの説明 ←いまここ
4. ユーザリストの表示
5. ユーザリストのペジネーション表示
6. ユーザ管理APIの追加
7. Vue.jsとAPIベースのユーザ管理アプリの追加準備
8. Vue.jsとAPIベースのユーザ管理アプリの追加
9. Vue.jsとAPIベースのユーザ管理アプリへのペジネーション追加
10. APIへのJWTAuth認証の追加
11. Vue.jsとAPIベースのユーザ管理アプリへの認証の追加

3. MVCとルーティングの説明

3.1 MVCの説明

いわゆるMVCモデルで構築されたWebアプリケーションは、M(モデル)はデータがセットされるオブジェクトをあらわし、V(ビュー)はブラウザに表示される画面、C(コントローラ)は制御ロジックをあらわしますが、LaravelはこのMVCモデルに準拠された形で開発されたPHPベースのWebアプリケーション・フレームワークです。

M(モデル)について

フレームワークは、データベースとの接続とORM(Object-Relational Mapping、オブジェクト関係マッピング)のしくみを提供し、M(モデル)にデータをセットしたり、セットされたデータをデータベースに反映することを容易にします。

V(ビュー)について

V(ビュー)はHTML画面をあらわしますが、HTMLやCSSだけでは静的なデータしか扱えず、M(モデル)にセットされる動的なデータを表示するために、フレームワークはHTMLの記述になるべく近しい表現の記述形式を提供してくれることが望まれます。Laravelはデフォルトでbladeとよばれるテンプレートエンジンを採用しており、[ファイル名].blade.phpというファイル名でHTMLに親和性のある方法で記述が可能です。

例えば、以下のサンプルは、コントローラでセットされたユーザ・モデルの配列$usersをループさせて、IDとユーザ名の行をテーブル表示するサンプルコードです。@から始まるノーテーションでロジックを記述したり、{{}}で囲んだエリアはPHPコードを記述することができる、といったルールで動的表示をサポートします。これによってデザイナがモックを作り、プログラマーに渡して実装を完成させるといった分担が可能になります。

<html>
<head><title>ユーザーリスト</title></head>
<body>
<table class="table table-striped table-bordered">
  <tr>
    <th>ID</th>
    <th>NAME</th>
  </tr>         
  <tr>
  @foreach($users as $user)
    <td>{{ $user->id }}</td>
    <td>{{ $user->name }}</td>
  @endforeach
  </tr>
</table>
</body>
</html>

C(コントローラ)について

C(コントローラ)は、前段のV(ビュー)からデータを取得し、加工したり、M(モデル)にデータをセットしたり、データベースに永続化したり、変数に値をセットして後段のV(ビュー)に渡したり、といった処理を行います。

ルーティングについて

Laravelは、画面遷移を表すルーティングの設定を非常にシンプルに行うことができます。MVCの説明で記載したとおり、画面遷移は「ブラウザ表示 → 入力・URI遷移 → C(コントローラ) → V(ビュー) → ブラウザ表示 → 入力・URI遷移 → C(コントローラ) → V(ビュー) → ブラウザ表示」の数珠つなぎで表現され、ブラウザにデータを入力してURIを指定してHTTPメソッドを実行することで、アクセスされたサーバ側ではC(コントローラ)を呼び出されますので、ルーティングは「URIとHTTPメソッド+呼び出されるC(コントローラ)+その先に遷移するV(ビュー)」のリストで表現することができます。

実際にここまでの実装で、userauthプロジェクトで定義されているルーティング定義を出力すると以下の通りとなります。

$ php artisan route:list
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
| Domain | Method   | URI                    | Name             | Action                                                                 | Middleware   |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
|        | GET|HEAD | /                      |                  | Closure                                                                | web          |
|        | GET|HEAD | api/user               |                  | Closure                                                                | api,auth:api |
|        | GET|HEAD | home                   | home             | App\Http\Controllers\HomeController@index                              | web,auth     |
|        | GET|HEAD | login                  | login            | App\Http\Controllers\Auth\LoginController@showLoginForm                | web,guest    |
|        | POST     | login                  |                  | App\Http\Controllers\Auth\LoginController@login                        | web,guest    |
|        | POST     | logout                 | logout           | App\Http\Controllers\Auth\LoginController@logout                       | web          |
|        | POST     | password/email         | password.email   | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail  | web,guest    |
|        | GET|HEAD | password/reset         | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest    |
|        | POST     | password/reset         |                  | App\Http\Controllers\Auth\ResetPasswordController@reset                | web,guest    |
|        | GET|HEAD | password/reset/{token} | password.reset   | App\Http\Controllers\Auth\ResetPasswordController@showResetForm        | web,guest    |
|        | GET|HEAD | register               | register         | App\Http\Controllers\Auth\RegisterController@showRegistrationForm      | web,guest    |
|        | POST     | register               |                  | App\Http\Controllers\Auth\RegisterController@register                  | web,guest    |
+--------+----------+------------------------+------------------+------------------------------------------------------------------------+--------------+

最後の列の「Middleware」は、認証形式やAPI呼び出しなのかWebアプリなのかといったミドルウェアレイヤーでの処理をあらわしますが、ここでは詳細の説明は割愛します。

このルーティングの定義は「routes」フォルダ下のファイルに定義されています。「routes/web.php」を詳しく見てみましょう。

routes/web.php
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

ここで定義された「Route::get('/', function () { return view('welcome'); });」は、URIが http://localhost:8000/ の場合「welcome.blade.php」を表示するという意味です。これに相当するルーティング定義は以下の通りです。Actionに相当するコントローラが設定されておらず、functionで代用されているため、ここではClosureと表現されています。

|        | GET|HEAD | /                      |                  | Closure                                                                | web          |

一方、「Auth::routes();」を見てみましょう。Authはフレームワークに同梱された「vendor/laravel/framework/src/Illuminate/Support/Facades/Auth.php」の以下の関数を意味します。

vendor/laravel/framework/src/Illuminate/Support/Facades/Auth.php
    /**
     * Register the typical authentication routes for an application.
     *
     * @return void
     */
    public static function routes()
    {
        static::$app->make('router')->auth();
    }

こちらいろいろ実装を見ていかないと解にいきつかないのですが、結局「vendor/laravel/framework/src/Illuminate/Routing/Router.php」の以下実装に相当します。

vendor/laravel/framework/src/Illuminate/Routing/Router.php
    /**
     * Register the typical authentication routes for an application.
     *
     * @return void
     */
    public function auth()
    {
        // Authentication Routes...
        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
        $this->post('login', 'Auth\LoginController@login');
        $this->post('logout', 'Auth\LoginController@logout')->name('logout');

        // Registration Routes...
        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
        $this->post('register', 'Auth\RegisterController@register');

        // Password Reset Routes...
        $this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
        $this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
        $this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
        $this->post('password/reset', 'Auth\ResetPasswordController@reset');
    }

これに相当するルーティング定義は以下の通りです。

|        | GET|HEAD | login                  | login            | App\Http\Controllers\Auth\LoginController@showLoginForm                | web,guest    |
|        | POST     | login                  |                  | App\Http\Controllers\Auth\LoginController@login                        | web,guest    |
|        | POST     | logout                 | logout           | App\Http\Controllers\Auth\LoginController@logout                       | web          |
|        | POST     | password/email         | password.email   | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail  | web,guest    |
|        | GET|HEAD | password/reset         | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest    |
|        | POST     | password/reset         |                  | App\Http\Controllers\Auth\ResetPasswordController@reset                | web,guest    |
|        | GET|HEAD | password/reset/{token} | password.reset   | App\Http\Controllers\Auth\ResetPasswordController@showResetForm        | web,guest    |
|        | GET|HEAD | register               | register         | App\Http\Controllers\Auth\RegisterController@showRegistrationForm      | web,guest    |
|        | POST     | register               |                  | App\Http\Controllers\Auth\RegisterController@register                  | web,guest    |

login関連が2定義、logout関連が1定義、password関連が4定義、register関連が2定義で数も内容もあっていることがわかります。

最後に、「Route::get('/home', 'HomeController@index')->name('home');」ですが、これに相当するルート定義は以下の通りです。

|        | GET|HEAD | home                   | home             | App\Http\Controllers\HomeController@index                              | web,auth     |

以上、ルート定義の場所と「php artisan route:list」コマンドを使ったルート定義の出力の説明でしたが、次にどのようなふるまいになるか具体的に見てみましょう。

例えば、http://localhost:8000/home というURIの場合、下記の設定が適用されます。

|        | GET|HEAD | home                   | home             | App\Http\Controllers\HomeController@index                              | web,auth     |

Middlewareが「web,auth」と定義されていますので、「auth(認証)」のルールが適用されて、ログインしていない場合は、http://localhost:8000/login に遷移し、ログインを促します。ログインがすんでいれば「App\Http\Controllers\HomeController@index」のコントローラが実行されます。これは「app/Http/Controllers/HomeController.php」ファイル内のindex関数をあらわします。実際の関数定義は以下の通りで、'home'という名前のV(ビュー)に遷移しなさい、という命令文になっています。

app/Http/Controllers/HomeController.php
    public function index()
    {
        return view('home');
    }

V(ビュー)は「resources/views」フォルダ下の[ビュー名].blade.phpというファイルに相当しますので、'home'ビューは「resources/views/home.blade.php」を表します。

以上、「3. MVCとルーティングの説明」が完了です。

次は、「4. ユーザリストの表示」です。

*参考:Laravelのユーザ関連のルート定義

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away