Laravel - 15. アクション - バリデーション

引き続きコントローラのアクションメソッドについて学習していきます。ここではリクエストパラメータのバリデーション(入力チェック)について学習します。これまでに学習してきたように、Laravelのアクションメソッドでは Request インスタンスを参照できます。この Request クラスにはリクエストパラメータを検証する validate メソッドが用意されています。

ここでは HelloController クラスの store メソッドにおいて、リクエストパラメータ text のバリデーションを実装します。具体的にはリクエストパラメータ text について、必須チェック、文字数のチェックの2つを実装することにします。

それではテキストエディタで app/Http/Controllers/HelloController.php を開いて、 store メソッドを以下のように修正します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Message;

class HelloController extends Controller
{
    public function index()
    {
        $title = "Hello Model!";
        $messages = Message::orderBy("id")->get();
        return view("hello/index", compact("title", "messages"));
    }

    public function create()
    {
        return view("hello/create");
    }

    public function store(Request $request)
    {
        $request->validate([
            'text' => 'required|max:10'
        ]);

        $text = $request->input("text");
        $all = $request->all();
        $ua = $request->header("User-Agent");
        $path = $request->path();

        Log::debug("All:", $all);
        Log::debug("UA:" . $ua);
        Log::debug("Path:" . $path);

        return "Request parameters: " . $text;
    }
}

store メソッドの先頭部分では $request->validate メソッドを使ってリクエストパラメータを検証しています。

        $request->validate([
            'text' => 'required|max:10'
        ]);

$request->validate メソッドは引数に連想配列を受け取ります。この連想配列のキーにリクエストパラメータの名前を指定し、キーに紐づく値にバリデーションルールを指定します。ここではリクエストパラメータ text について、バリデーションルールとして必須チェック( required )と最大文字数チェック( max:10 )を定義しています。また今回のように1つのリクエストパラメータに複数のバリデーションルールを定義するときは | で区切るようにします。

その他の定義可能なバリデーションルールについては、https://laravel.com/docs/6.x/validation#available-validation-rules を参照してください。

$request->validate メソッドは、リクエストパラメータが不正な場合、呼び出し元画面に処理をリダイレクトします。このとき入力エラーメッセージ( $errors )も合わせて生成されるので、ビューの中からエラーメッセージを参照できるようになります。

続いてビューファイル( resources/views/hello/create.blade.php )にエラーメッセージの表示処理を追加してみましょう。

@extends('layout.app')

@section('content')
<form action="store" method="post">
  @csrf

  <input type="text" name="text" value="{{ old('text') }}">
  <input type="submit" value="send">
</form>
@if ($errors->any())
<ul>
  @foreach ($errors->all() as $error)
    <li>{{ $error }}</li>
  @endforeach
</ul>
@endif
@endsection

入力フォームの定義の後の部分に入力エラーメッセージの出力処理を追加しています。Laravelのバリデーションによって生成された $errors 変数にはリクエストパラメータごとの複数のエラーメッセージが格納されています。そのため @foreach ディレクティブを使ってエラーメッセージを順に処理しています。また入力フォームの input タグの value 属性に {{ old('text') }} とすることで、入力したデータを再表示できます。

動作確認

HelloControllerstore アクションにバリデーションを追加したので、PHPのビルトインWebサーバを使ってWebアプリケーションを起動してみましょう。次のようにコマンドを入力します。

$ php artisan serve --host 0.0.0.0
Laravel development server started: http://0.0.0.0:8000

続いてブラウザを起動してWebアプリケーションにアクセスしてみましょう。

http://localhost:8000/hello/create

入力フォームが表示されるので、メッセージを空の状態で送信ボタンをクリックしてみましょう。

画面に入力エラーメッセージ(必須入力)が表示されます。

次に11文字以上の入力を試してみましょう。

この場合も同様に入力エラーメッセージ(文字数超過)が表示されます。

参考:入力エラーメッセージのカスタマイズ

デフォルトの入力エラーメッセージ(英語)は resources/lang/en/validation.php で定義されています。 また resources/lang フォルダ下に言語ごとのメッセージファイルを追加することで日本語のメッセージも定義できます。

まとめ

  • Request クラスの validate メソッドを使うことでリクエストパラメータを検証できる
  • リクエストパラメータのバリデーションに違反が発生した場合は呼び出し元画面にリダイレクトする
  • Bladeビューにおいて $errors 変数を参照することでエラーメッセージを表示できる