YuHo のブログ

Laravel, PHP, JavaScript

Laravel 5.6 でブログサイトを制作する2 #8 サブドメイン用の Route を作成する

今回は、既存の blog アプリにサブドメイン用の Route を付け足します。
現在作成中のサイトのドメインは "blog.test" となっているはずです。
サブドメインとは "sub-domain.blog.test" のような物のことです。
このアプリでは上記の "sub-domain" の部分には各ユーザーのユーザー名(アカウント名)を受け付けることにします。
ユーザー名(アカウント名)とは、ここでは、各ユーザーに1つずつ割り当てられる独自の文字列を意味します。
"User001" のような物のことです。
Twitter では "@User001" などとなっている部分のことです。

開発

サブドメインを Route 処理できるようにする

まずは web.phpサブドメインを受け付けるための Route を作成します。

[blog/routes/web.php]

<?php

Route::domain('{userName}.blog.test')->group(function () {
    Route::get('/', 'UserController@show');
});

Route パラメータに制約を付ける

次にサブドメイン用の Route の Route パラメータに制約を付けておきます。
ここでは、「アルファベット1文字から始まり、それにアルファベットまたは数字が0個以上続く物」という制約にします。
これはなくてもいいですが、あるほうが少しだけいいです。

[blog/app/Providers/RouteServiceProvider.php]

<?php

public function boot()
{
    Route::pattern('userName', '[a-zA-Z][a-zA-Z0-9]*');

    parent::boot();
}

パラメータとモデルを明示的に結びつける

次にサブドメインの Route パラメータと User モデルを明示的に結びつけます。
サブドメインのパラメータは今回は "userName" となっているため、暗黙に結びつけるなら、ユーザーコントローラーの使用するメソッドの対応する引数を "App\User userName" とする必要があり、ややこしいため、こうします。

[blog/app/Providers/RouteServiceProvider.php]

<?php

public function boot()
{
    Route::pattern('userName', '[a-zA-Z][a-zA-Z0-9]*');

    parent::boot();

    Route::model('userName', App\User::class);
}

パラメータからモデルを取り出す方法を指定する

最後に、パラメータからモデルを取り出す方法を指定します。
既定の方法だと、パラメータと対応するモデルのテーブルの id カラムを比べてしまいます。
今回は、パラメータと対応するモデルの userName カラムを比べます。

[blog/app/Providers/RouteServiceProvider.php]

<?php

public function boot()
{
    Route::pattern('userName', '[a-zA-Z][a-zA-Z0-9]*');

    parent::boot();

    Route::model('userName', App\User::class);
    Route::bind('userName', function ($value) {
        return App\User::where('nameName', $value)->first() ?? abort(404);
    });
}

解説

サブドメインの Route を作成する

  1. Route::domain() メソッドを利用する
  2. 引数はサブドメインの形式を表す文字列
  3. Route::domain() メソッドに group() メソッドを鎖付けする
  4. 引数は Route を作成するためのクロージャ
[blog/routes/web.php]

<?php

Route::domain('{userName}.blog.test')->group(function () {
    Route::get('/', 'UserController@show');
});

Route パラメータに制約を付ける

  1. Route::pattern() メソッドを仕様する
  2. 第一引数が対象 Route パラメータの名称
  3. 第二引数が制約のための正規表現
  4. boot() メソッドの parent::boot の前に置く
[blog/app/Providers/RouteServiceProvider.php]

<?php

Route::pattern('userName', '[a-zA-Z][a-zA-Z0-9]*');

パラメータとモデルの結びつける

  1. Route:model() メソッドを仕様する
  2. 第一引数が対象の Route パラメータの名称
  3. 第二引数が対応するモデル
  4. boot() メソッドの parent::boot の後に置く
[blog/app/Providers/RouteServiceProvider.php]

<?php

Route::model('userName', App\User::class);

パラメータからモデルを取り出す方法を指定する

  1. Route::bind() メソッドを利用する
  2. 第一引数は対象の Route パラメータの名称
  3. 第二引数は方法を指定するクロージャ
  4. boot() メソッドの parent:;boot の後に置く
[blog/app/Providers/RouteServiceProvider.php]

<?php

Route::bind('userName', function ($value) {
    return App\User::where('nameName', $value)->first() ?? abort(404);
});