プログラミング

Laravelのフォームリクエストを使ってバリデーションを実装する方法

投稿日:

WebサイトやWebアプリにおいてユーザーが入力すためのフォームを目にすることや利用することは多いのではないでしょうか?

このフォームにユーザーが何でもかんでも入力していいわけではありません。サイト作成者が意図しない値をユーザーが入力する場合はできるだけ避けなければなりません。

そのためにユーザーがフォームに入力できる値を制限することをバリデーションと言います。

Laravelではバリデーションをかけるための方法がいくつか存在します。その中でも、FormRequestを使ったバリデーション方法をこの記事では紹介していきたいと思います。

入力フォームの作成

リクエストを送るためのフォームを作っていきましょう。

まずはコントローラーの作成です。

FormControllerというコントローラーを作ります。

php artisan make:controller FormController

作成したFormController.phpの中身を下記の通りに実装します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FormController extends Controller
{
    public function index()
    {
        return view('form.index');
    }
}

Viewを返すだけの単純なコードです。

また、ルーティングの設定もしておきます。

Route::get('/form', 'FormController@index');

次にform/index.blade.phpを作成していきましょう。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>Laravel</title>

    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@200;600&display=swap" rel="stylesheet">
    <link href="{{ mix('css/app.css') }}" rel="stylesheet" type="text/css">
  </head>
  <body>
    <form action="/form/test" method="POST">
      @csrf
      <input type="text" name="message">
      <button type="submit" class="btn btn-primary">送信</button>
    </form>

    <script src="{{ mix('js/app.js') }}"></script>
  </body>
</html>

formタグの中に入力用のinputタグと送信用のボタンを配置しています。

また、@csrfという記述がありますね。

これはLaravelが標準で使えるようにしているCSRF対策で、フォームでリクエストを送る際にはこちらの記述をしないと下記のようなエラー画面となります。

@csrfの記述をすることで、リクエストが送信できるようになります。

ですが、このままではどんな値でも入力できてしまいますね。

入力を制限するようにバリデーションをかけていきましょう。

FormRequestを継承したClass

FormRequestとはRequestファサードを継承したもので、バリデーションのルールやメッセージをカスタマイズするのに特化しています。コントローラーやモデルから切り分けることで、可動性や保守性を上げることも期待できます。

FormRequestのクラスであるTestRequestをコマンドで作成します。

php artisan make:request TestRequest

作成されたTestRequest.phpのファイルの中身は下記のようになっています。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class TestRequest 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 [
            //
        ];
    }
}

FormRequestクラスを継承したTestRequestの中にauthorizeメソッドとrulesメソッドが定義されているのが、分かりますね。

authorizeメソッド

boolean型のfalseが戻り値として返しています。

このauthorizeメソッドはTestRequestの使用を許可するどうかを設定するためのメソッドです。

falseが設定されているということはデフォルトでは使用許可されていない状態です。

rulesメソッド

戻り値として空の配列をしているところに、バリデーションを定義していきます。

messagesメソッド

また、フォームリクエストを作成したデフォルトの状態では定義されていませんが、messagesメソッドを定義することができます。

messageメソッドではバリデーションエラー時のエラー文を定義することができます。

rulesメソッド同様に配列形式で戻り値を返す必要があります。

バリデーションの作成

それではバリデーションを実際に実装していきましょう。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

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

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

    /**
     * @return array
     */
    public function messages()
    {
        return [
            'message.required' => '必ず何か入力してください。'
        ];
    }
}

1つずつ解説していきます。

public function authorize()
{
    return true;
}

authorizeメソッドでtrueを戻り値として返すことで、TestRequestの利用を許可します。

public function rules()
{
    return [
        'message' => 'required'
    ];
}

rulesメソッドの戻り値である連想配列のキーにはinputタグのname属性の値を指定します。

値にはinputタグにかけたいバリデーションルールを指定します。

requiredを指定するとそのinputタグは空にすることは出来ず、必須項目とすることが出来ます。

もちろん、バリデーションルールはrequiredだけでなく、数多くあります。バリデーションルールの一覧はLaravelの公式ドキュメントで掲載されていますので、ぜひ参考にしてください。

Laravel 7.x バリデーション(https://readouble.com/laravel/7.x/ja/validation.html)

public function messages()
{
    return [
        'message.required' => '必ず何か入力してください。'
    ];
}

messagesメソッドでは、rulesメソッドで制限したバリデーションルールに対してエラーだった場合のエラーメッセージをカスタマイズすることができます。

messagesメソッドの戻り値の連想配列のキーにはrulesメソッドで定義した連想配列の「キー」.「値」として指定します。

値にその時のエラーメッセージを指定することが出来ます。

また、エラーメッセージは送信元のviewで下記のように記述することでエラーが発生したときに表示することが出来ます。

<div>{{ $errors->first('message') }}</div>

コントローラーの編集

バリデーションの作成をすることが出来ましたが、このままではバリデーションを使用することが出来ていません。

コントローラーで作成したバリデーションを使用するように紐づけをしてあげる必要があります。

それではコントローラーを編集していきましょう。

<form action="/form/test" method="POST">
  @csrf
  <input type="text" name="message">
  <button type="submit" class="btn btn-primary">送信</button>
</form>
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    ...省略...
  </head>
  <body>
    <p>{{ $message }}</p>

    <script src="{{ mix('js/app.js') }}"></script>
  </body>
</html>
Route::post('/form/test', 'FormController@test');
public function test(Request $request)
{
    return view('form.test', ['message' => $request->message]);
}

今回、FormControllerのtestメソッドがフォームからのリクエストを受けるメソッドとして定義しました。

Requestクラスでフォームからの値を受け取ることが出来ましたね。

バリデーションを適用させる場合は、Requestクラスではなく先ほど作成したTestRequestクラスで受け取るように定義することで紐づけることができます。

use App\Http\Requests\TestRequest;

class FormController extends Controller
{
    ...省略...

    public function test(TestRequest $request)
    {
        return view('form.test', ['message' => $request->message]);
    }
}

これでフォームリクエストでのバリデーションの実装が出来ました。

挙動を確認してみましょう。

何も入力せずに、送信ボタンを押下してみましょう。

TestRequestクラスのmessagesメソッドで定義したエラーメッセージが無事に表示されています。

まとめ

Laravelのフォームリクエストを使ってバリデーションを行う方法を解説してきました。

少しやることが多いなと感じた方もいるかもしれませんが、この機能は非常に便利です。

フレームワークなど無しでバリデーションを行おうとすれば、if文や正規表現などを駆使してアルゴリズムを定義する必要があり、とても大変です。

そういったことなしにバリデーションを行えるLaravelのフォームリクエストは非常に便利です。

バリデーションはWebシステム開発において必須の機能なので、ぜひフォームリクエストを使いこなして開発効率を上げていきましょう。

-プログラミング

Copyright© みぎさんドットコム , 2021 All Rights Reserved Powered by STINGER.