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>
まあまあ普通のシンプルなログインフォームですよね。
これでログインボタンを押した場合は、コントローラにemail
、password
の値が送信されます。
(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を書いていましたが、みなさんお好きにどうぞ。。。
.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バリデーション講座を行いました。
標準だけでもものすごいパターンのバリデーションができるので、めちゃくちゃおすすめです!