LoginSignup
6
2

More than 5 years have passed since last update.

Laravelのバリデーションについて複数あるじゃないか!

Posted at

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文字以下

という条件にしようと思うので

controller
$this->validate($request, [
       'book_id'    => 'integer|between:1,12',
       'book_name'  => 'string|between:1,12',
]);

とこのように書くことができます。

この状態でフォームを送信してもなにもメッセージは得られません

のでviewの方で以下のような記載をしてください

【特定の場所で全表示】

view
@if(count($errors) > 0)
    <ul>
        @foreach ($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
    </ul>
@endif

【特定の場所で特定のエラーを出す】

view
@if($errors->has('book_id'))
    <div class="error">
        <p>{{ $errors->first('book_id') }}</p>
    </div>
@endif

この状態で違反する内容でフォームを送信しましょう

エラーメッセージとして
よくわからないエラーが出ると思います。

これをカスタマイズするには以下のようにします

controller
$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

利用するためには
コントローラでこのリクエストクラスを利用する設定をします

controller
use App\Http\Requests\RegisterFormRequest;

...

public function registerForm(RegisterFormRequest $request)

あとはメソッド単位でホゲホゲしてあげる。

以上!!!

[Validation2] 自分で作っちゃおうぜ

自分で作るメリットとしては
細かく自由にカスタマイズし放題
デメリットとしては時間がかかる…?
だと思います

コントローラで作成

まず条件としては上と同じく

name 条件
book_id 整数
1文字以上12文字以下
book_name 文字列
1文字以上12文字以下

こちらでやります。

まずはrequestされてきた値を配列に格納し
トリムなんかを施して
バリデーション用のメソッドへ飛ばします

controller
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させます

controller
public function isValidate(array $inputs) {

    $errors = [];
    $errors = [
    'book_id'   => "",
    'book_name' => "",
    ];

return $errors

その値を表示させるためには
viewの方で以下のようにしてあげましょう

※すごい雑なやり方です。
本来であればboolでやるのが理想かと

view
@if($formErrors['book_id']!="")
    <div class="error">
        <p>{{ $formErrors['book_id'] }}</p
    </div>
@endif

これで下準備はできました

あとはバリデーションチェックです

バリデーション

必須項目のチェック

isValidateのメソッド
// BookIDのチェック
if (!empty($inputs['book_id'])) {
    $str = "";
    $str = $inputs['book_id'];
    if ($this->isNumeric($str) === false){
        $errors['book_id'] = 'BookIDは整数のみじゃよ!';
    }
}
isNumericのメソッド
function isNumeric($str) {
    if (!preg_match("/^[0-9]+$/", $str)) {
        # 半角数字以外が含まれていた場合、false
        return false;
    }
    return true;
}

こんな感じですかね…。
これで1つのフォームで複数のエラーを持たせてあげてforeachで回すのがいいかもしれません。

まとめ

今回

エラーでもその入力値で問い合わせはする、フォームも入力値のまま
エラーメッセージは表示させたい
ということだったので下のような感じになりました。

もし上記の条件でもっといいやり方があれば
教えてください。

6
2
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
6
2