laravelのバリデーションを使っていると、「この項目だけじゃなくて、別の値も見て判定したい」と思う場面はありませんか?
- laravel標準のバリデーションだけでは実現できないチェックがしたい
- 複数の値を参照してバリデーションしたいがやり方が分からない
- 特定の画面でしか使わないからコントローラで完結させたい
複雑なシステムだとlaravel標準のバリデーションだけではできないことが多いと思います。私自身laravelを使用した案件で、ほとんど標準のバリデーションを使用せずにチェックロジックを実装するなんてこともありました。
今回紹介する記事では、その案件でも実際に実装した方法です。共通化する必要がなかったため、サービスプロバイダーは使用せず、コントローラ内でバリデーションを完結させています。
- 複数の値を使った複雑な条件でのバリデーションが実装できる
- バリデーションロジックをきれいに分離できる
- 実務で使えるlaravelのカスタムバリデーションが理解できる
実際のユースケースを想定し、簡単なサンプルコードをもとに紹介していきます。
また、laravel公式仕様に沿った内容となっておりますので、ぜひ参考にしてみてください。
実装
実装する流れ
- コントローラ内でカスタムバリデーションを定義する
- 入力項目「名前」に対してhiddenで持っているフラグを見てエラーとするかを判定する
- フラグが「1」でない場合にエラーとする
- 「名前」にカスタムバリデーションを割り当てる
controller
$validatorのgetDataメソッドを使用して送信されたデータを取得するのが今回のポイントになります。
getDataから送信されてきたデータを取得し、今回はそのなかの「input_flg」をみて判定をしています。
「custom_check」はバリデーションの名前を自由につけられます。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\users;
use Illuminate\Support\Facades\Validator;
class BlogController extends Controller
{
public function gettest(Request $request) {
return view('test');
}
public function posttest(Request $request) {
// カスタムバリデーションを定義
Validator::extend('custom_check', function ($attribute, $value, $parameters, $validator){
// 送信されたデータを取得し、変数へ格納
$data = $validator->getData();
// フラグを見る
if ($data['input_flg'] != 1) {
return false;
}
return true;
});
// カスタムバリデーションの割り当て
$rule = [
'name' => 'custom_check',
];
// エラーメッセージの作成
$messages = [
'name.custom_check' => 'カスタムチェックエラー',
];
// バリデーション
$validator = Validator::make($request->all(), $rule, $messages);
if($validator->fails()){
// エラー時の処理
dd($validator->errors());
}
dd('エラーなし');
}
}
「’name’ => ‘custom_check’」とし、画面の名前に対してカスタムバリデーションを割り当てます。
エラーメッセージも同様に連想配列の値に定義します。

エラー(「input_flg」が1でない)場合、エラーの中身を表示しています。

エラーがない(「input_flg」が1)場合、最後の「dd(‘エラーなし’)」まで処理が走ります。
blade

<body>
<h3>テストフォーム</h3>
<form action="{{ route('posttest') }}" method="POST">
@csrf
{{-- ↓この値を見る --}}
<input type="hidden" name="input_flg" value="0">
<table border="1" style="border-collapse: collapse;" id="table">
<thead>
<tr>
<th>名前</th>
<th>年齢</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" name="name" value=""></td>
<td><input type="text" name="age" value=""></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2" style="text-align: end;">
<input type="submit" value="送信">
</td>
</tr>
</tfoot>
</table>
</form>
</body>(紹介)外からの変数を参照するパターン
$request->input(‘input_flg’)でバリデーション定義の外で変数を準備し、それをuseして使用するパターンも消化敷いておきます。
これは画面からの値だけでなく、DBから取得した値やバリデーションの前に別の判定をして、その値を使用したいときに便利です。
// カスタムバリデーション
$input_flg = $request->input('input_flg'); // input_flgを受け取りカスタムバリデーションに値を渡す
Validator::extend('custom_check', function ($attribute, $value, $parameters, $validator) use ($input_flg){
// 送信されたデータを取得し、変数へ格納
$data = $validator->getData();
// フラグを見る
if ($input_flg != 1) {
return false;
}
return true;
});まとめ
今回は、複数の値を参照してバリデーションをする方法を紹介しました。
laravel標準のバリデーションでは対応しづらい「ほかの入力値を見て判定したい」といったケースでも、カスタムバリデーションを使用すれば柔軟に対応できます。
特に、今回のように特定の画面でしか使用せず、共通化するほどでもない場合は、コントローラ内で完結させる実装がシンプルでおすすめです。
また、過去に配列に対してバリデーションを行う方法についても紹介しておりますので、是非参考にしてみてください。
laravelで配列に対してバリデーションをする方法
