Laravelにはデフォルトで洗練された
「フォームリクエストバリデーション」というものがある。
これは
・フォームを含む各リクエストに対して、それぞれ固有のバリデーションを設定できる。
・バリデーションエラー時には、入力値とエラー情報を付与して前のページに自動的にリダイレクトする。
・バリデーションをパスした時に初めてコントローラー内の処理に移る。
というものである。
非常に優秀かつ優れたものだと思う。
目的
バリデーションは複数あるので
自分の求める目的に合わせて利用してほしい
そして誰かの参考になればよいと思い記事をかく
環境
名前 | バージョン |
---|---|
Laravel | 5.0 |
php | 5.6 |
macOS Sierra | 10.12.6 |
入力値の受け取り方
検索時
- name:book_id
- name:book_name
の2つのフォームがあるとする
[Validation1] Laravel Validationを利用する
上記でも述べましたが
Laravelのデフォルトで搭載されている
バリデーション機能は
・フォームを含む各リクエストに対して、それぞれ固有のバリデーションを設定できる。
・バリデーションエラー時には、入力値とエラー情報を付与して前のページに自動的にリダイレクトする。
・バリデーションをパスした時に初めてコントローラー内の処理に移る。
となっております。
直コントローラ書き
まずコントローラの
(Request $request)があるメソッドに
$this->validate($request, [
'book_id' => '条件',
'book_name' => '条件',
]);
このような記載をする
条件に関してはこちらを参考にしてください
Laravelのバリデーションで指定できる内容をざっくりまとめ直しました。
今回は
name | 条件 |
---|---|
book_id | 整数 1文字以上12文字以下 |
book_name | 文字列 1文字以上12文字以下 |
という条件にしようと思うので
$this->validate($request, [
'book_id' => 'integer|between:1,12',
'book_name' => 'string|between:1,12',
]);
とこのように書くことができます。
この状態でフォームを送信してもなにもメッセージは得られません
のでviewの方で以下のような記載をしてください
【特定の場所で全表示】
@if(count($errors) > 0)
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
@endif
【特定の場所で特定のエラーを出す】
@if($errors->has('book_id'))
<div class="error">
<p>{{ $errors->first('book_id') }}</p>
</div>
@endif
この状態で違反する内容でフォームを送信しましょう
エラーメッセージとして
よくわからないエラーが出ると思います。
これをカスタマイズするには以下のようにします
$this->validate($request, [
'book_id' => 'integer|between:1,12',
'book_name' => 'string|between:1,12',
],[
'book_id.integer' => '整数でお願い',
'book_name.between' => 'ここは:minから:maxまでの長さなのじゃよ',
]);
リクエストクラスの作成
Artisanコマンドで一発で作成可能です
$ php artisan make:request RegisterFormRequest
利用するためには
コントローラでこのリクエストクラスを利用する設定をします
use App\Http\Requests\RegisterFormRequest;
...
public function registerForm(RegisterFormRequest $request)
あとはメソッド単位でホゲホゲしてあげる。
以上!!!
[Validation2] 自分で作っちゃおうぜ
自分で作るメリットとしては
細かく自由にカスタマイズし放題
デメリットとしては時間がかかる…?
だと思います
コントローラで作成
まず条件としては上と同じく
name | 条件 |
---|---|
book_id | 整数 1文字以上12文字以下 |
book_name | 文字列 1文字以上12文字以下 |
こちらでやります。
まずはrequestされてきた値を配列に格納し
トリムなんかを施して
バリデーション用のメソッドへ飛ばします
public function registerForm(Request $request) {
// 検索フォームに入力された値を取得する
$input = $request->all();
// 前後の全角スペースを削除する
$inputs = [];
foreach($input as $key => $val) {
$inputs[$key] = trim($val, " \t\n\r\0\x0B ");
$inputs[$key] = ltrim($val, "0");
}
// エラーチェック
$formErrors = $this->isValidate($inputs);
その値を受け取ります
何かのエラー処理を行った後その値をreturnさせます
public function isValidate(array $inputs) {
$errors = [];
$errors = [
'book_id' => "",
'book_name' => "",
];
return $errors
その値を表示させるためには
viewの方で以下のようにしてあげましょう
※すごい雑なやり方です。
本来であればboolでやるのが理想かと
@if($formErrors['book_id']!="")
<div class="error">
<p>{{ $formErrors['book_id'] }}</p
</div>
@endif
これで下準備はできました
あとはバリデーションチェックです
バリデーション
必須項目のチェック
// BookIDのチェック
if (!empty($inputs['book_id'])) {
$str = "";
$str = $inputs['book_id'];
if ($this->isNumeric($str) === false){
$errors['book_id'] = 'BookIDは整数のみじゃよ!';
}
}
function isNumeric($str) {
if (!preg_match("/^[0-9]+$/", $str)) {
# 半角数字以外が含まれていた場合、false
return false;
}
return true;
}
こんな感じですかね…。
これで1つのフォームで複数のエラーを持たせてあげてforeachで回すのがいいかもしれません。
まとめ
今回
エラーでもその入力値で問い合わせはする、フォームも入力値のまま
エラーメッセージは表示させたい
ということだったので下のような感じになりました。
もし上記の条件でもっといいやり方があれば
教えてください。