LoginSignup
0
0

More than 3 years have passed since last update.

【Larave】バリテーション

Last updated at Posted at 2020-07-14

こちらの記事は以下の書籍を参考に執筆しました

フィールドごとのエラー表示

テンプレをこのように修正する。

<p>{{$msg}}</p>
@if(count($errors)>0)
<p>入力に問題があり。再入力</p>
@endif
<form action="/hello" method="post">
  <table>
    @csrf
    @if($errors->has('name'))
    <tr><th>ERROR</th><td>{{$errors->first('name')}}</td></tr>
    @endif
    <tr><th>name:</th><td><input type="text" name="name" value="{{old('name')}}"></td></tr>
    @if($errors->has('mail'))
    <tr><th>ERROR</th><td>{{$errors->first('mail')}}</td></tr>
    @endif
    <tr><th>mail:</th><td><input type="text" name="mail" value="{{old('mail')}}"></td></tr>
    @if($errors->has('age'))
    <tr><th>ERROR</th><td>{{$errors->first('age')}}</td></tr>
    @endif
    <tr><th>age:</th><td><input type="text" name="age" value="{{old('age')}}"></td></tr>
    <tr>
      <th></th><td><input type="submit" value="send"></td>
    </tr>
  </table>
</form>

出典:PHPフレームワークLaravel入門 第2版

これでフィールドごとにエラーを表示できる。

firstでメッセージを取り出す

    @if($errors->has('name'))
    <tr><th>ERROR</th><td>{{$errors->first('name')}}</td></tr>
    @endif
    <tr><th>name:</th><td><input type="text" name="name" value="{{old('name')}}"></td></tr>

出典:PHPフレームワークLaravel入門 第2版

$ifディレクティブで$errors->has('name')をチェックしている。
hasはエラーが発生しているかをチェックする。

$errors->has(項目名)

出典:PHPフレームワークLaravel入門 第2版

エラーが発生していれば$errro->first('name')という値を出力しているがfirstは指定した項目最初のエラーメッセージを取得する。

$error->first(項目名)

出典:PHPフレームワークLaravel入門 第2版

これでname="name"のinputで発生したエラーが表示できる。

firstとget

firstは最初のエラーメッセージしか得られない
すべてのエラーメッセージを取得したい場合はgetを使う。

$変数=$error->get(項目名)

出典:PHPフレームワークLaravel入門 第2版

これ配列でまとめて返される。
以下はエラーメッセージを取得する3つのメソッド

名前 説明
all すべてのエラーメッセージを配列で取得
first 指定した項目の最初のエラーメッセージを文字列で取得
get 指定した項目のエラーメッセージをすべて取得

ここまでをまとめると
@ifで\$error->hasのチェックをし、trueなら\$error->firstや#error->getでエラーメッセージを取り出して表示する。

@errorディレクティブを使う

しかし上記の手順よりも簡単にバリテーションチェックとエラーメッセージを活用できるのが\$errorディレクティブ

エラーメッセージの表示

#error(名前)
...$messageでメッセージを表示
@end$error
@errorディレクティブは()に指定した項目のエラーをチェックしこのディレクトティブ内に記述した内容を表示する

このディレクティブでは発生したエラーメッセージが**\$message**という変数に渡される

##使ってみる。


```php5
<p>{{$msg}}</p>
@if(count($errors)>0)
<p>入力に問題があり再入力</p>
@endif
<form action="/hello" method="post">
  <table>
    @csrf
    @error('name')
    <tr><th>ERROR</th><td>{{$message}}</td></tr>
    @enderror
    <tr><th>name:</th><td><input type="text" name="name" value="{{old('name')}}"></td></tr>
    @error('mail')
    <tr><th>ERROR</th><td>{{$message}}</td></tr>
    @enderror

    <tr><th>mail:</th><td><input type="text" name="mail" value="{{old('mail')}}"></td></tr>
    @error('age')
    <tr><th>ERROR</th><td>{{$message}}</td></tr>
    @enderror

    <tr><th>age:</th><td><input type="text" name="age" value="{{old('age')}}"></td></tr>
    <tr>
      <th></th><td><input type="submit" value="send"></td>
    </tr>
  </table>
</form>

出典:PHPフレームワークLaravel入門 第2版

$ifを#errornに書き換えただけ。これでさっきと同じようにエラーが表示される。

バリデーションをカスタマイズ

フォームリクエストとカスタムバリデーションでバリデーションをカスタマイズする。

フォームリクエストについて

validateメソッドはコントローラに処理を書く必要があり、入力値検証はホアに任せたい。そこでフォームリクエストが生まれた。

フォーム用拡張リクエスト

フォームリクエストはリクエストをフォーム利用のために拡張したもの。
LaravelehaクライアントからのリクエストはRequestクラスのインスタンスとして送られる。このRequestを継承して作成されたのがFromRequest
これでフォームに関する機能をリクエストを組み込める。

送信されたフォームの内容をチェックするのはコントローラにあるよりもリクエストの内部で処理してくれる方がスマート。

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

ではフォームリクエストを作成していく。

>出典:[PHPフレームワークLaravel入門 第2版](https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AFLaravel%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798060992/ref=tmm_hrd_title_0?_encoding=UTF8&qid=1595991312&sr=1-2)


php artisan make:request HelloRequest

出典:PHPフレームワークLaravel入門 第2版

Http/Requestに作成される。

作成されたフォームリクエストはFormRequestを継承し、Requestを継承しリクエストの機能をベースにバリデーションなどのフォーム処理機能が追加されている。

FormRequestには以下の2つのメソッドが追加されている。

authorize

このフォームリクエストを利用するアクションでフォームリクエストの利用が許可されているかどうかを示す。戻り値がfalseならHttpExtentionという例外が発生してフォーム処理ができなくなる。

rules

適応されるバリデーションの検証ルールを設定する。

HelloRequestを修正する

    public function authorize()
    {
        if($this->path()=='hello'){
          return true;
        }else {
          return false;
        }
    }
    public function rules()
    {
        return [
          'name'=>'required',
          'mail'=>'email',
          'age'=>'numeric|between:0,150',
        ];
    }

出典:PHPフレームワークLaravel入門 第2版

\$this->path()でアクセスしたパスをチェックしている。
ここでhello以外は利用っできないようにしている。
バリデーションに関する部分をすべて消し、単にviewでテンプレとmsg変数を返すだけに修正する。

POST送信時のコントローラのアクションを修正する。

//use App\Http\Requests\HelloRequest;を追記する
    public function post(HelloRequest $request){
      return view('hello.index',['msg'=>'正しく入力された']);
    }

出典:PHPフレームワークLaravel入門 第2版

ポイントは引数がRequestからHelloRequestに変わっていること
これでHelloRequestをの内容を元にバリデーションされる。

メッセージのカスタマイズ

もう少しカスタマイズしてみる。
これまでのエラーを日本語にしてみる。

FromRequestのmessageメソッドをオーバーライドする。
HelloRequestに追加する。

    public function messages()
    {
        return [
        'name.required'=>'名前は必須項目',
        'mail.email'=>'メアドは必要',
        'age.numeric'=>'整数で記入',
        'age.between'=>'0から150で入力',
      ];
    }

出典:PHPフレームワークLaravel入門 第2版

このmessageはFromRequestがバリデーション機能をエラーメッセージを必要とした時に呼びされるメソッド。配列でまとめられいて中身を見ると、

>出典:[PHPフレームワークLaravel入門 第2版](https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AFLaravel%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798060992/ref=tmm_hrd_title_0?_encoding=UTF8&qid=1595991312&sr=1-2)


'name.required'=>'名前は必須項目',

出典:PHPフレームワークLaravel入門 第2版

「'項目名.ルール名'=>'メッセージ'」というメッセージ情報を記述する。
これはそれぞれのフィールドごとに用意した1つ1つのルールごとに用意する。

バリデータの作成

バリデーション機能ではFormRequestにあるvalidateメソッドを使って行われる。
validateはRequestインスタンスと検証ルールの引数を渡されることで自動的にフォームの値のチェックを行う、問題があればGETのページにリダイレクトしてフォームの再表示をする。

場合によってはエラーがあったらフォームページに行くのではなく、別の処理をさせたい場合もある。こういうときはバリデータを独自に用意して処理できる。
バリデータはバリデーションを行う機能のことでLaravelではValidatorというクラスがある。

コントローラーのvalidateメソッドを呼び出さず、このValidatorクラスのインスタンスを作成して処理することでバリデーションの処理をカスタマイズできる。

バリデータを使ってみる

バリデータは送信されたフォームを受け撮ったアクション内で作成する。
今回はpostメソッドに書いていく

//use Validator;を追加しておく
    public function post(Request $request)
    {
        $validator=Validator::make($request->all(), [
        'name'=>'required',
        'mail'=>'email',
        'age'=>'numeric|between:0,150',
      ]);
        if ($validator->fails()) {
            return redirect('/hello')->withErrors($validator)->withInput();
        }
        return view('hello.index', ['msg'=>'正しく入力された']);
    }

出典:PHPフレームワークLaravel入門 第2版

/helloにアクセスステ確認してみると独自のバリデータでチェックが行われる。

バリデータ利用の基本

バリデータはValidatorインスタンスを作成するだけで使えるが、makeで作る必要がある。

$validator=Validator::make(値の配列,ルールの配列);

出典:PHPフレームワークLaravel入門 第2版

引数 説明
第1引数 チェックする値をまとめた配列。フォームをそのままチェックするなら$request->all()でOK
第2引数 検証ルール情報を配列で。

エラーのチェックはこのように。

if ($validator->fails()) {...エラー時の処理...}

出典:PHPフレームワークLaravel入門 第2版

failsはバリデーションのチェックに失敗したかどうかを調べるもの。
戻り値がtureならエラーが発生している。

入力フォームへのリダイレクト

ここではエラー発生時にGETのページにリダイレクトしているが、振るうにリダイレクトしたらエラーメッセージやフォーム値が渡せない。そこでこのようにしている。

return redirect('/hello')
       ->withErrors($validator)
       ->withInput();

出典:PHPフレームワークLaravel入門 第2版

リダイレクトはredirectで行う。
指定のアドレスに移動させるだけならredirectだけでいい。

今回はエラーメッセージとフォーム入力情報をリダイレクトに追加している。
それがwithErrorsとwithInput

withErrors

引数にValidatorインスタンスを渡して、Validatorで発生したエラーメッセージをリダイレクト先まで引き継げる。

withInput

送信されたフォームの値をそのまま引き継げる。

クエリ文字列にバリデータを適用する

バリデータはフォーム以外のチェックにも使える。
例としてクエリ文字列で渡された値をチェックする。
コントローラのindexメソッドを修正する。

    public function index(Request $request)
    {
      $validator=Validator::make($request->query(),[
        'id'=>'required',
        'pass'=>'required',
      ]);
      if($validator->fails()){
        $msg='クエリーに問題がある。';
      }else {
        $msg='ID/PASSを受け付けた。フォームを入力';
      }
        return view('hello.index', ['msg'=>$msg,]);
    }

出典:PHPフレームワークLaravel入門 第2版

/hellにそのままアクセスするとモンぢがあると表示され/hello?id=xx&pass=xxの形式で送信するとうまく表示される。

ここではValidator::makeメソッドの引数にkのような値を指定している。

$request->query()

出典:PHPフレームワークLaravel入門 第2版

これは送信されたクエリー文字列を配列形式でまとめたものを返す。

>出典:[PHPフレームワークLaravel入門 第2版](https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AFLaravel%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798060992/ref=tmm_hrd_title_0?_encoding=UTF8&qid=1595991312&sr=1-2)


/hello?id=taro&pass=yamada
↓
['id'=>'taro','pass'=>'yamada']

出典:PHPフレームワークLaravel入門 第2版

第2引数ではこのように指定されている。

      [
        'id'=>'required',
        'pass'=>'required',
      ]

出典:PHPフレームワークLaravel入門 第2版

検証ルールがまとめられている。

あとは$validator->fails()をチェックして表示するメッセージを設定するだけ。
「チェックする項目と値を連想配列にしてValidator::makeに渡す。」という長エレがわかればどんな値でもバリデーションでチェックができる。

エラーメッセージのカスタマズ

バリデータを利用する場合のエラーメッセージのカスタマイズはValidator::makeを呼び出す時に指定できる。

validator=Validator::make(値の配列,ルール配列,メッセージ配列);

出典:PHPフレームワークLaravel入門 第2版

第3引数にエラーメッセージ配列を用意する。これは先のエラーメッセージカスタマイズ時に使用したものと同じもの。
理解のためにPOST送信された時にメッセージ表示をしてみる。

    public function post(Request $request)
    {
        $rules=[
          'name'=>'required',
          'mail'=>'email',
          'age'=>'numeric|between:0,150',
        ];
        $messages=[
          'name.required'=>'名前は必須項目',
          'mail.email'=>'メアドは必要',
          'age.numeric'=>'整数で記入',
          'age.between'=>'0から150で入力',
        ];
        $validator=Validator::make($request->all(), $rules, $messages);
        if ($validator->fails()) {
            return redirect('/hello')
            ->withErrors($validator)
            ->withInput();
        }
        return view('hello.index', ['msg'=>'正しく入力された']);
    }

出典:PHPフレームワークLaravel入門 第2版

これで日本語でエラーが表示される。

条件に応じてルールを追加する

必要に応じてルールを追加したい場合はValidatorクラスのsometimesというメソッドを使う

sometimes

処理を実行した結果によって新たにルールを追加できる。

$validator->sometimes(項目,ルール名,クロージャ);

出典:PHPフレームワークLaravel入門 第2版

クロージャはこのような形をしている。

function($input){
  ...処理を実行...
  return 真偽値;
}

出典:PHPフレームワークLaravel入門 第2版

\$inputには入力された値をまとめたものが渡される。
ここから\$input=>nameのように取り出せる。
戻り地は真偽値。

真偽値 説明
true 何もしない
false somerimesで指定したルールを指定の項目に追加

ルール追加をする。

コントローラのpostメソッドを優勢

    public function post(Request $request)
    {
        $rules=[
          'name'=>'required',
          'mail'=>'email',
          'age'=>'numeric',
        ];
        $messages=[
          'name.required'=>'名前は必須項目',
          'mail.email'=>'メアドは必要',
          'age.min'=>'0際以上で入力',
          'age.max'=>'200歳以下で入力',
        ];
        $validator=Validator::make($request->all(), $rules, $messages);

        $validator->sometimes('age','min:0',function($input){
          return !is_int($input->age);
        });

        $validator->sometimes('age','max:200',function($input){
          return !is_int($input->age);
        });

        if ($validator->fails()) {
            return redirect('/hello')
            ->withErrors($validator)
            ->withInput();
        }
        return view('hello.index', ['msg'=>'正しく入力された']);
    }

出典:PHPフレームワークLaravel入門 第2版

今回は'age'=>'numeric'だけになっている。
minルールを見てみる

$validator->sometimes('age','min:0',function($input) 
{
   return !is_int($input->age);
});

出典:PHPフレームワークLaravel入門 第2版

クロージャで!is_int($input->age)の値を返している。
これにより\$input->ageの値が整数の場合はfalseが返され、'min:0'のルールが'age'に追加される。

0
0
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
0
0