Posted at

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

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

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

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


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

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

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

「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バリデーション講座を行いました。

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