LoginSignup
17
17

More than 5 years have passed since last update.

laravelでformのバリデーションをしよう!(カスタマイズあり)

Posted at

Laravelにはformバリデーションができる便利な機能があります!!

今回はそれを紹介していきます!

標準でもかなりの種類のバリデーションをサポートをしていますが、バリデーションを自分仕様にカスタマイズしたい時もあるので、カスタマイズバージョンも説明します!

formバリデーションはどんなことができるか

例えば、こんなログイン画面があるとします

スクリーンショット 2019-03-03 13.17.20.png

ユーザーがメールアドレスを入力せずにログインボタンを押した場合は、

スクリーンショット 2019-03-03 13.18.47.png

「emailは必須項目です。」というエラーが出ます。

仕様としてはこんな感じです!

じゃあ次はどうやってバリデーションをするかみてみましょう〜

Laravelでformバリデーションをしよう!(標準装備編)

バリデーションをする前のbladeをみる

先ほどのログイン画面のformの部分のbladeはこんな感じにしています。
(バリデーションを実装する前です。)


<form class="register-form" action="/login" method="post">
    {{ csrf_field() }}
    <div class="email-login-form-title">メールアドレス</div>
    <div class="email-login-form-input"><input type="email" name="email" value="{{old('email')}}"></div>

    <div class="email-login-form-title">パスワード</div>
    <div class="email-login-form-input"><input type="password" name="password"></div>
    <button type="submit">ログイン</button>
</form>

まあまあ普通のシンプルなログインフォームですよね。

これでログインボタンを押した場合は、コントローラにemailpasswordの値が送信されます。
(inputのnameの部分が名前で、テキストボックスに入力された値がコントローラにいきます。)

コントローラでバリデーションをしてみる

LoginControllerの中にあるログインをするための関数です。


class LoginController extends Controller
{
.
.
    protected $redirectToAfterLogin = '/home';

    /**
     * login
     */
    public function login(Request $request)
    {
        $validator = $request->validate([       // <-- ここがバリデーション部分
            'email' => 'required|exists:users',
            'password' => 'required|min:8',
        ]);
        $user = User::where('email', $request->email)->first();
        Auth::login($user);
        return redirect($this->redirectToAfterLogin);
    }
.
.
.
}

もうなんかみたらなんとなくわかると思うんですけど、emailには、「必須項目」「ユーザーが既にデータベースに存在する」というバリデーション、passwordには「必須項目」「8文字以上」というバリデーションをつけています。

バリデーション部分の書き方については、


$request->validate([
    '$requestの中に入っている要素' => '実行したいバリデーションを「|」区切りで書く',
]);

そして、大事なところは、$request->validate...のところでバリデーションに引っかかったらそこで処理を中止して、ビューにエラーを返すということです。

サポートURL: 全54種類!Laravel 5.7のバリデーション実例
サポートURL: Laravel公式サイト: バリデーション

ビューでエラーを表示する

ビューでエラーを表示するには、ビューをこのように変更します。


<form class="login-form" action="/login" method="post">
    {{ csrf_field() }}
    <div class="email-login-form-title">メールアドレス</div>
    <div class="email-login-form-input"><input type="email" name="email" value="{{old('email')}}"></div>
    @if ($errors->first('email'))   <!-- ここ追加 -->
        <p class="validation">※{{$errors->first('email')}}</p>
    @endif

    <div class="email-login-form-title">パスワード</div>
    <div class="email-login-form-input"><input type="password" name="password"></div>
    @if ($errors->first('password'))   <!-- ここ追加 -->
        <p class="validation">※{{$errors->first('password')}}</p>
    @endif
    <button type="submit">ログイン</button>
</form> 

emailのバリデーションのエラーなら、$errors->first('email')で取得できます。

全てのerrorを一気に表示したいなら、こんな感じになります


@if ($errors->any())
    @foreach ($errors as $error)
        <p class="validation">{{$error}}</p>
    @endforeach
@endif

CSSでvalidationのスタイルを追加したら終わり!

validationでエラーが出た時の、エラーメッセージのスタイルはぜひ統一しておきたいので、
validationのcssを書いたら終了です。

先ほどのログイン画面はちなみにこういうcssを書いていましたが、みなさんお好きにどうぞ。。。
css
.validation {
display: inline;
font-size: 0.8rem;
color: #FA5C65;
margin: 0.3rem;
}

ちょっと待って!エラー文が英語じゃねえか!!

そうなんです。最初はエラー文は英語で用意されているんです。

僕はこれをまんまパクりました↓

Laravel5.3 で超ラクにバリデーションしてエラーメッセージを変更する

ただ、今はlaravel5.7だか5.8だかその辺りなので、気をつけてください。

Laravelでformバリデーションをする(カスタマイズ編)

カスタマイズって難しそうに聞こえますけど、結構簡単です!

じゃあ例えば、カタカナしか入力して欲しくないフォームを作るとしましょう。

まずは、コマンドを叩きます。


$ php artisan make:rule ValidateKana

ValidateKanaの部分は、名前はなんでも大丈夫です。

そうすると、app/Rules/ValidateKana.phpができています。

これをみると最初はこうなっていると思います


<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class ValidateKana implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        // 
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        // 
    }
}

passes関数のところに、どういうバリデーションをしたいかを記述し、
message関数のところに、エラーメッセージに内容を記述します。

カタカナ以外の文字が送られてきた場合、「カタカナで入力してください」と返すとすると、ValidateKanaはこうなります。
(passesでfalseがreturnされた時にエラーが発動します。$valueは入力された値をさしています。)


<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class ValidateKana implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        if (preg_match("/^[ヲ-゚ー ]+$/u", $value) || preg_match('/^[ァ-ヾ]+$/u', $value)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'カタカナで入力してください';
    }
}

ほんで、Controllerの方では、このように書きます。
new ValidateKana()で先ほどのカスタマイズしたカタカナバリデーションが発動しています。

class LoginController extends Controller
{
    use App\Rules\ValidateKana;
.
.
.
    public function 〇〇
    {
        $validator = $request->validate([
            'koumokumei' => ['required', 'string', new ValidateKana()],
        ])
    }

注意点

ちなみに、お気付きの方もいらっしゃるかもしれませんが、
カスタマイズしたバリデーションを追加すると、「|」バリデーションの書き方は区切りじゃなくなるんです。

今までは['required|string']のように書いていましたが、カスタマイズが登場するだけで
['required', 'string', new ValidateKana()]とコンマ区切りにしないとエラーが出ますので御気をつけください。

補足:バリデーションの機能を使わずにバリデーションっぽいことしたい!!

そんなニーズがあるかはわかりませんが、
こうやったらできます。


return redirect('/')->withErrors("エラーが発生しました");

これでビューの方に$errorsを渡します。

終わりに

Laravelで簡単formバリデーション講座を行いました。

標準だけでもものすごいパターンのバリデーションができるので、めちゃくちゃおすすめです!

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