【Laravel】FormRequestクラスを使ってカスタムバリデーション
もくじ
Laravelでバリデーション
Laravelで入力チェックを実装するには、Request
を使います。
POSTリクエストで入力された値を簡単にバリデーションチェックできます。
Requestクラス
まずはFormRequest
クラスを使わず、Laravelが初めから用意しているRequest
クラスを使って簡単にバリデーションしてみます。
ルーティング
Route::get('/request', 'PostController@create')->name('request'); Route::post('/request', 'PostController@store');
ビュー
<form action="{{ route('request') }}" method="POST"> @csrf <div class="form-group"> <label for="title" class="col-form-label">タイトル</label> <input type="text" class="form-control" id="title" name="title" placeholder="タイトル" value="{{ old('title') }}"/> @error('title') <div class="text-danger">{{ $message }}</div> @enderror </div> <div class="form-group"> <label for="body" class="col-form-label">本文</label> <textarea type="text" class="form-control @error('body') is-invalid @enderror" id="body" name="body" placeholder="本文">{{ old('body') }}</textarea> @error('body') <div class="text-danger">{{ $message }}</div> @enderror </div> <div class="form-group row justify-content-center"> <button type="submit" class="btn btn-primary">送信</button> </div> </form>
inputタグ
<input type="text" class="form-control @error('title') is-invalid @enderror" id="title" name="title" placeholder="タイトル" value="{{ old('title') }}" />
わかりやすいように改行しています。
name
属性は、バリデーションするinput
タグを識別するので必須です。
old関数
value
属性にあるold
関数は、入力値がもしバリデーションに引っかかってエラーになった時に値を維持しておくためのものです。仮にold
関数を設置しなかった場合、エラーになるたびに入力した値は空になります。
Laravelではoldグローバルヘルパ関数も用意しています。とくにBladeテンプレートで直前の入力値を表示したい場合に、oldヘルパは便利です。指定した文字列の入力が存在していないときは、nullを返します。
エラーメッセージの表示
@error('title') <div class="text-danger">{{ $message }}</div> @enderror
エラーになったときに表示するメッセージを設置します。
@error('title')
name="title"
のinput
がエラーになった時
{{ $message }}
ここにエラーメッセージが表示されます。
スタイルの変更
今はエラーになるとメッセージが文字と枠線が赤色になるだけですが、クラスを変更してスタイルを簡単に変更できます。
class="form-control @error('title') is-invalid @enderror" // これを class="form-control" // これに変更
エラーになっても枠線は赤くなりません。
<div class="alert alert-danger">{{ $message }}</div> // 変更
エラーメッセージをボックスのように変更もできます。
コントローラー
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class PostController extends Controller { public function create() { return view('/request'); } public function store(Request $request) { // バリデーション実行 $request->validate([ 'title' => 'required|max:5', 'body' => 'required', ]); } }
Requestクラスの使用
public function store(Request $request)
store
メソッドの引数にRequest
クラスを指定し、入力された値を格納します。
$request
にform
タグで入力した値が全て入っています。
use宣言
use Illuminate\Http\Request;
Request
クラスを使うには必ずはじめにuse宣言しておきましょう。
バリデーション実行
$request->validate([ 'title' => 'required|max:5', 'body' => 'required', ]);
左辺がinput
のname
属性を指定し、右辺がバリデーションのルールを指定します。
required
: 入力必須max
: 最大数
他にもLaravelは多様なルールを用意してくれています。
公式ドキュメントを確認して使ってみましょう。
カスタマイズ
FormRequestクラスを使うことによって、バリデーションをカスタマイズできます。
controllerでのvalidate()
が不要になり、エラーメッセージもカスタマイズできるので日本語化もできます。
詳しくは後述します。すぐ読みたい場合はFormRequestクラスから。
ブラウザで確認
初期表示
バリデーション実行
FormRequestクラス
ではFormRequestクラスを使うとどうなるか比較してみます。
ファイル作成
FormRequestクラスのファイルを作成します。
$ php artisan make:request StoreBlogPost Request created successfully.
successfully
と出れば成功です。
make:request
コマンドを実行するとapp/Http/Request
ディレクトリが生成され、そこにファイルが設置されます。すでにディレクトリが存在する場合は内包されます。
ルーティングとビュー
これはFormRequestクラスを作る前と同じで大丈夫です。
リクエスト
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class StoreBlogPost extends FormRequest { public function rules() { return [ 'title' => 'required|max:5', 'body' => 'required', ]; } public function messages() { return [ 'title.required' => 'タイトルは必須です', 'title.max' => 'タイトルは5文字までです', 'body.required' => '本文は必須です', ]; } }
コントローラー
<?php namespace App\Http\Controllers; use App\Http\Requests\StoreBlogPost; class PostController extends Controller { public function create() { return view('/request'); } public function store(StoreBlogPost $request) { // バリデーションの記述は不要 } }
use宣言
use App\Http\Requests\StoreBlogPost;
先ほど作ったStoreBlogPostをuse宣言します。これがないと、エラーになりますので忘れずに。
StoreBlogPostクラスの使用
public function store(StoreBlogPost $request)
store
メソッドの引数にStoreBlogPost
クラスを指定します。
これにより$request
に格納された入力値はコントローラメソッドが呼び出される前にバリデーションを行います。
よって、コントローラーの中でバリデーションの処理を記述する必要がなくなります。(もちろん、記述することも可能です)
入力した値の取得
これで検証してみます。
入力値を全て取得
$request->all() // array(3) { ["_token"]=> string(40) "(トークン)" ["title"]=> string(9) "あああ" ["body"]=> string(9) "いいい" }
トークンも取得できます。
指定のinputを取得
$request->title $request['title'] $request->input('title')
入力された値を使って何かしらの処理をしたいときは、上記のコードを使って入力値を使用できます。
なお、いずれも入力値が取得できます。
echo($request->title); // 結果:あああ echo($request['title']); // 結果:あああ echo($request->input('title')); // 結果:あああ
存在チェック
$request->has('title') // 結果は真偽値
結果が真偽値なので、if文などで活躍します。
if ($request->has(['title'])) { $title = $request->title; echo($title . "と入力されました。"); } // 結果:あああと入力されました。
除外
$request->except(['title']) // array(2) { ["_token"]=> string(40) "(トークン)" ["body"]=> string(9) "いいい" }
name="title"
以外の入力値とトークンを取得できます。
ほかにもあるので、公式ドキュメントで確認してみてください。