Laravel 5.7 受け取った Request を検証(バリデーション)する

メモ:  Category:blog

「Laravel 5.7 でフォームからデータを受け取る( Request )」でフォームからデータを受け取ることができるようになりました。

次は、受け取ったデータが望む形となっているかバリデーションを実装してみます。

Laravel のバリデーションは、バリデーションに失敗すると自動的に元のフォームにリダイレクトしてくれます。

バリデーションの実装

コントローラーのメソッドに次のようにバリデーションを実装します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ContactController extends Controller
{
    //
    public function send(Request $request){
        $validationData = $request->validate([
            'email' => 'required|email',
            'subject' => 'required|max:255',
            'message' => 'required',
        ]);

        $email = $request->input('email');
        $subject = $request->input('subject');
        $message = $request->input('message');

        return 'メッセージを送信しました。('.$subject.')';
    }
}

検証したい項目に対し、バリデーションルールを設定し validate へ渡します。このバリデーションルールに基づいて検証が実施され、エラーの場合は呼び出し元のフォームへ自動的にリダイレクトします。バリデーションに成功した場合は、次の処理を実行します。

バリデーションルールについては、多くの種類があるためマニュアルを参照します。

テンプレートの処理

バリデーションに失敗するとビューに Illuminate\View\Middleware\ShareErrorsFromSession が結合され $errors 変数としてエラー情報を参照できるようになります。

そこで、エラーがあった場合フォームで確認できるようテンプレートを次のように作成します。

@extends('layouts.default')

@section('title','contact')

@section('content')
<form action="send" method="post">
<div class="form-group">
    <label for="InputEmail">メールアドレス</label>
    <input type="email" name="email" class="form-control" id="InputEmail">
    @if($errors->has('email'))
        <p class="text-danger">{{ $errors->first('email')}}</p>
    @endif
</div>
<div class="form-group">
    <label for="InputSubject">件名</label>
    <input type="text" name="subject" class="form-control" id="InputSubject">
    @if($errors->has('subject'))
        <p class="text-danger">{{ $errors->first('subject')}}</p>
    @endif
</div>
<div class="form-group">
    <label for="InputMessage">メッセージ</label>
    <textarea name="message" id="InputMessage" class="form-control" cols="40" rows="4"></textarea>
    @if($errors->has('message'))
        <p class="text-danger">{{ $errors->first('message')}}</p>
    @endif
</div>
@csrf
<button type="submit" class="btn btn-primary">送信</button>
</form>
@endsection

テンプレートに @if という制御構文を追加しています。 @if の部分では、エラーが発生していたらエラーメッセージを表示するよう設定しています。また、 $errors->first() の部分は、指定したフィールドの最初のエラーメッセージを取得します。

実際にエラーを発生させると次のようにエラーメッセージが追加されたフォームが表示されます。

バリデーションエラー時のフォーム

直前のデータを取得する

エラー表示ができるようになりましたが、間違って入力されたデータを見せたい場合もあります。

この場合、old グローバルヘルパ関数というものを使用すると直前の値を取得できるようです。

例えば、 value 属性を次のように作成します。

<input type="email" name="email" class="form-control" id="InputEmail" value="{{ old('email') }}">

bluenote by BBB