Laravelで簡単にフォームのバリデーションを行う2通りの方法

 

今回はLaravelの機能を使用して、フォームのバリデーションをする方法の記事になります。

コントローラに直接記述する方法で解説し、それをフォームリクエストを使用するように書き換えたバージョンも紹介できればと思います。

執筆時点でLaravelのバージョンは7.6になります。

 

今回バリデーションしてみる内容

 

今回は以下のようなユーザ情報登録用のフォームを想定して見たいと思います。

<form method="POST" action="/action">
    {{ csrf_field() }}
    名前:<input type="text" name="name"><br>
    メール:<input type="text" name="email"><br>
    年齢:<input type="text" name="age"><br>
    <input type="submit" value="送信">
</form>

 

コントローラーでバリデーション

 

先程作成したフォームの送信先のコントローラを作成します。コントローラ作成にはartisanコマンドが便利ですね。

$ php artisan make:controller UserController

 

するとコントローラができますので、登録用のstoreメソッドを作成します。

ここで、デフォルトでuseしてあるIlluminate\Http\Requestクラスをメソッドの引数に与えます。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        // 処理
    }
}

 

これで準備は完了したので、バリデーション本体を記述していきます。

バリデーションを行うには$request->validate()を呼び出します。

書き方は以下の通りです。

// array $rules : バリデーションルール
// array $messages : メッセージ(省略可)
// array $attributes : メッセージ中のアトリビュートの指定(省略可)

$request->validate($rules, $messages, $attributes);

 

実際にどう適用すればいいのかといいますと、以下のようにしてみましょう。

class UserController extends Controller
{
    public function store(Request $request) 
    { 
        $request->validate([
            'name' => 'required', // requiredというルールを適用
            'email' => 'required|email', // required, emailを適用
            'age' => 'integer|between:0,100', // integer, between:0,100を適用
        ]);
    } 
}

 

このようにフォームのname属性の値に適用したいルールを記述するだけで勝手にバリデーションしてくれます。

ここで出てきたルールは以下のとおりです。

 

ルール 説明
required 必須項目
email メールアドレス形式であるか
integer 整数形式であるか
between:0,100 0から100の間か

 

これら以外にもたくさんのバリデーションルールがありますので、一度公式マニュアルに目を通してみることをおすすめします。

バリデーション 7.x Laravel

 

この$request->validate()に成功した場合には処理を続行し、失敗した場合には元のページにエラーメッセージ付きでリダイレクトします。

 

エラーメッセージの表示

 

ではどうやってエラーメッセージを表示するのかといいますと、エラーメッセージは$errors変数に格納されていますので、これを使用します。

// すべて出力
@foreach ($errors->all() as $error)
    {{ $error }}
@endforeach

// 最初の1つだけ出力
{{ $errors->first() }}

 

エラーメッセージの編集

 

次にエラーメッセージの編集方法を2通り紹介します。

 

言語ファイルを編集する方法

共通のエラーメッセージは「resources/lang/〇〇/validation.php」を編集することで、設定します。

〇〇の部分は日本語ならja, 英語ならenといった具合です。

 

/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
*/
// ルールごとの共通メッセージ
'required' => ':attribute は必須です',
'email' => ':attribute はメールアドレス形式である必要があります。',
'integer' => ':attribute は整数形式である必要があります。',
'between' => ':attribute は :min から :max の間である必要があります。',

/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
*/
// ageのbetweenルールのときのメッセージ
'custom' => [
    'age' => [
        'between' => ':attribute は :min 歳から :max 歳の間である必要があります。',
    ],
],

/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
*/
// :attribute のところに当てはめる文字
'attributes' => [
    'name' => '名前',
    'email' => 'メール',
    'age' => '年齢',
],

 

$request->validate()に直接記述する方法

共通のものではなくそのページ独自のメッセージを使用したい場合もあると思います。

なので他の方法として、$request->validate()の第2引数と第3引数を使用して編集することもできます。

 

$request->validate([
    'name' => 'required',
    'email' => 'required|email',
    'age' => 'integer|between:0,100',
],
[
    'required' => ':attribute は必須です。',
    'email' => ':attribute はメールアドレス形式である必要があります。',
    'integer' => ':attribute は整数形式である必要があります。',
    'age.between' => ':attribute は :min 歳から :max 歳の間である必要があります。',
],
[
    'name' => '名前',
    'email' => 'メール',
    'age' => '年齢',
]);

 

フォームに送信前の値を残す

 

ここまでで、バリデーション、メッセージの表示とやってきましたが、あと一つやっておきたいことがあります。

それはフォーム送信後、バリデーションエラーになった際にフォームの入力値がクリアされてしまうことです。

 

それを防ぐためにLaravelではセッションに古いフォームデータが保存されています。これはoldというヘルパー関数で取り出せます。

// $name : フォームのname属性
// $default : デフォルトの値(省略可)
old($name, $default)

 

これをフォームのvalue属性にセットして置くことで、より良いフォームになったと言えます。

<form method="POST" action="/action">
    {{ csrf_field() }}
    名前:<input type="text" name="name" value="{{ old('name') }}"><br>
    メール:<input type="text" name="email" value="{{ old('email') }}"><br>
    年齢:<input type="text" name="age" value="{{ old('age') }}"><br>
    <input type="submit" value="送信">
</form>

 

さてここまでで、コントローラを使用したバリデーションの一連の作成方法でした。

最後にコントローラから分離してバリデーションする方法を書いておきます。コントローラの肥大化が防げるので個人的におすすめです。

 

フォームリクエストを使用する方法

 

まずは、バリデーションをするためにFormRequestを継承したクラスを作成します。

これもartisanコマンドで簡単に作成できます。

php artisan make:request UserStoreRequest

 

すると以下のようなファイルがapp/Http/Requests配下に作成されています。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UserStoreRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return false;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
        ];
    }
}

 

ここに必要なメソッドを追加していきます。

これの$rulesをrulesメソッドの返り値に、$messagesをmessagesメソッドの返り値に、$attributesをattributesメソッドの返り値にすればよいのです。

 

先程の例を用いると以下のようにします。(コメントは省略してます)

class UserStoreRequest extends FormRequest
{
    public function authorize()
    {
        return true; // 注:trueに変える
    }
    public function rules()
    {
        return [
            'name' => 'required',
            'email' => 'required|email',
            'age' => 'integer|between:0,100',
        ];
    }

    public function messages()
    {
        return [
            'required' => ':attribute は必須です。',
            'email' => ':attribute はメールアドレス形式である必要があります。',
            'integer' => ':attribute は整数形式である必要があります。',
            'age.between' => ':attribute は :min 歳から :max 歳の間である必要があります。',
        ];
    }

    public function attributes()
    {
        return [
            'name' => '名前',
            'email' => 'メール',
            'age' => '年齢',
        ];
    }
}

「resources/lang/〇〇/validation.php」の共通設定を使用する場合はmessages()とattributes()は不要です。

 

また、コントローラを修正します。

デフォルトでIlluminate\Http\Requestを使用しているので、App\Http\Requests\UserStoreRequestに変更しておきます。

// Illuminate\Http\Requestから変更
use App\Http\Requests\UserStoreRequest;

class UserController extends Controller
{
    // 引数をRequestからUserStoreRequestに変更
    public function store(UserStoreRequest $request)
    {
        // バリデーションは記載の必要なし
        // 処理
    }
}

 

これでフォームリクエストを使用した場合にもバリデーションを導入できました。

コントローラもスッキリしていいですね。

 

最後に

 

バリデーションはいかがだったでしょうか。

バリデーションって実装しようとすると、いろんなパターンを考慮しなくてはいけなくて大変だったりするのですが、それもLaravelを使えば簡単にできてしまいます。