LoginSignup
3
4

More than 3 years have passed since last update.

Laravelで入力値エラーチェック(validate)を実装する

Last updated at Posted at 2020-05-11

目次

Laravelの記事一覧は下記
PHPフレームワークLaravelの使い方

Laravelバージョン

動作確認はLaravel Framework 7.19.1で行っています

前提条件

eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています

エラーチェッククラスの作成

(1) コマンドラインで
cd sample
php artisan make:rule SampleRule
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Rules/SampleRule.phpが現れます

(2) /sample/app/Rules/SampleRule.phpに変数を追加し、コンストラクタ、passesメソッド、messageメソッドを修正します

SampleRule.php
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class SampleRule implements Rule
{
    private $word = null;

    public function __construct($word)
    {
        $this->word = $word;
    }

    public function passes($attribute, $value)
    {
        if ($value === $this->word) {
            return true;
        } else {
            return false;
        }
    }

    public function message()
    {
        return trans('validation.SampleRule');
    }
}

passesメソッドがエラーチェック処理です
falseを返すとエラーがあったと判定されたことになります
messageメソッドはエラー時のエラーメッセージです。エラーメッセージとして指定したvalidation.SampleRuleはこの後(3)でvalidation.phpに記載します

(3) /sample/resources/lang/en/validation.phpに追記
SampleRule要素を追記
attributes要素配列にsample_input要素、single_array.sample_input要素、multi_array.*.sample_input要素追記

validation.php
<?php

return [
‥‥
    'SampleRule' => ':attribute does not match the secret word.',
‥‥
    'attributes' => [
        'sample_input'               => 'sample word1',
        'single_array.sample_input'  => 'sample word2',
        'multi_array.*.sample_input' => 'sample word3',
    ],
‥‥
];

SampleRule要素が先ほど(2)でエラーメッセージとして指定したメッセージとなります
attributes要素配列のsample_input要素、single_array.sample_input要素、multi_array.*.sample_input要素はHTMLのname属性値と論理名とのマッピングです。
single_array.sample_inputというのはsingle_array[sample_input]というname属性値
multi_array.*.sample_inputというのはmulti_array[0][sample_input]、multi_array[1][sample_input]‥‥というname属性値に相当します
SampleRuleエラーメッセージの:attributeを置換します

フォームリクエストの作成

上記で作成したRuleクラスを使うクラスを作成します
(1) コマンドラインで
cd sample
php artisan make:request SampleRequest
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Http/Requests/SampleRequest.phpが現れます

(2) SampleRequest.phpへ追記
use App\Rules\SampleRule;

(3) SampleRequest.phpのauthorizeメソッド、rulesメソッドを下記に修正

SampleRequest.php

    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'sample_input'               => [new SampleRule('sample'), 'required'],
            'single_array.sample_input'  => [new SampleRule('sample'), 'required'],
            'multi_array.*.sample_input' => [new SampleRule('sample'), 'required'],
        ];
    }

SampleRequestのauthorizeメソッドはこのリクエストを使用する権限があるかどうかチェックです。falseを返すとこのリクエストを使用するURLにはアクセスできなくなります

SampleRequestのrulesメソッドはこのリクエストで使用する入力値チェックを定義します

new SampleRuleというのは先ほど作成した入力値チェッククラスです

'required'というのはLaravelが提供してくれている入力値チェックです
Laravelが提供してくれている入力値チェックは下記を参照してください
Laravel 7.x バリデーション 使用可能なバリデーションルール

ここから
ここまで
書かれている英単語を使用できます
今回は
必須 'required'
を使用しました
入力値を必須ではなく任意にしたい場合は
NULL許可 'nullable'
を使用します

SampleRequestのrulesメソッドが返している配列の要素名はHTMLのname属性値です
single_array.sample_inputというのはsingle_array[sample_input]というname属性値
multi_array.*.sample_inputというのはmulti_array[0][sample_input]、multi_array[1][sample_input]‥‥というname属性値に相当します
さきほどのresources/lang/en/validation.phpのattributes配列に対応します

Controllerにメソッド追加

(1) /sample/app/Http/Controllers/SampleController.phpに下記を追記
use App\Http\Requests\SampleRequest;

(2) /sample/app/Http/Controllers/SampleController.phpにvalidation1メソッド、validation2メソッドを追記

    public function validation1()
    {
        return view('sample.validation1');
    }

    public function validation2(SampleRequest $request)
    {
        $data = [
            'msg' => '入力チェックOK',
        ];
        return view('sample.validation2', $data);
    }

validation2メソッドの引数が先ほど作成したSampleRequestになっています
これでvalidation2へのリクエストが来た時に、SampleController#validation2が呼び出される前にSampleRequest#rulesに書いたエラーチェックが実行されます
そこでエラーチェックに引っかかったらリダイレクトが実行され、
さらに、blade.phpでold関数が使えるように、入力値が次のユーザーリクエストの処理中だけ利用できるフラッシュデータとしてセッションに保存されます

(3) /sample/routes/web.phpに下記を追記
Route::get('sample/validation1', 'SampleController@validation1');
Route::post('sample/validation2', 'SampleController@validation2');

viewの作成

(1) /sample/resources/views/sample/validation1.blade.phpファイル作成

validation1.blade.php
<html>
    <head>
        <title>sample</title>
    </head>
    <body>

        <form action="{{ url('sample/validation2') }}" method="post">
            @csrf
            @error('sample_input')
                @foreach ($errors->get('sample_input') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>sample word1<input type="text" name="sample_input" value="{{ old('sample_input') }}"></div>

            @error('single_array.sample_input')
                @foreach ($errors->get('single_array.sample_input') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>sample word2<input type="text" name="single_array[sample_input]" value="{{ old('single_array.sample_input') }}"></div>

            @error('multi_array.0.sample_input')
                @foreach ($errors->get('multi_array.0.sample_input') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>sample word3<input type="text" name="multi_array[0][sample_input]" value="{{ old('multi_array.0.sample_input') }}"></div>
            <input type="submit" >
        </form>

    </body>
</html>


@errorは、指定した属性のバリデーションエラーメッセージがあるかを判定します
$errorsは、Illuminate\Support\MessageBagのインスタンスです
$errors->getで指定した属性のバリデーションエラーメッセージを取得します

(2) /sample/resources/views/sample/validation2.blade.phpファイル作成

validation2.blade.php
<html>
    <head>
        <title>sample</title>
    </head>
    <body>
        {{$msg}}
    </body>
</html>

動作確認

http://localhost/laravelSample/sample/validation1

a.png
何も入力せず送信ボタンをクリックしてみる

b.png
SampleRuleとrequiredのチェック結果が出力される
requiredのエラーメッセージは/sample/resources/lang/en/validation.phpにあらかじめ記載されています

c.png
sampleではない文字列を入力して送信ボタンをクリックしてみる
SampleRuleのチェック結果が出力される

d.png
sampleという文字列を入力して送信ボタンをクリックしてみる

e.png
validation2に遷移できました

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4