ウェブログラム ~学習するな実践せよ~

Laravelのフォームリクエストバリデーション

2018/11/21

ここではLaravelの基本的なバリデーションについて学びます。

Laravelは非常に沢山のバリデーションが用意されていますし、自分でカスタマイズすることも出来るので、 非常に使いがってが良いです。

基本的なバリデーションの使い方に慣れ、自由に入力チェック出来るようになりましょう。

ここでは飲食店などの「店舗」のモデルを例にして試していきます。 店舗(stores)の情報は以下の通りにしました。

  • name(店舗名)
  • email(メールアドレス)
  • address(住所)
  • tel(電話番号)
  • text(店舗概要)

前提条件

ルーティング

routes/web.php
// 店舗登録画面
Route::get('/stores', 'StoreController@index');
// 店舗登録
Route::post('/stores', 'StoreController@create');

コントローラ

コントローラはルーティングにかかれているメソッドを2つ作成しました。

index()ではビューを表示するだけです。 create()で登録画面より送信されたリクエストを受け取って、dd()メソッドで中身を表示しています。 $req->all()とすることで、送信されたパラメータのみが取得できます。

app/Http/Controllers/StoreController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class StoreController extends Controller
{
// 登録画面の表示
public function index()
{
return view('stores/index');
}
// 登録処理
public function create(Request $req)
{
dd($req->all());
}
}

 ビュー(登録画面)

以下のようなとてもシンプルなフォームを作成してみました。

 

resources/views/stores/index.blade.php
<!doctype html>
<html lang="ja">
<head>
</head>
<body>

<form method="POST" action="/stores">
名前: <input type="text" name="name"><br>
メール: <input type="email" name="email"><br>
住所: <input type="text" name="address"><br>
電話: <input type="text" name="tel"><br>
店舗情報: <textarea name="text"></textarea><br>
{{ csrf_field() }}
<input type="submit">
</form>
</body>
</html>


このフォームから店舗登録を行って、 バリデーションチェックをし、エラーがあれば同一ページに エラーを表示してあげるというのをしましょう。

モデル

今回実際にDBへの登録はしません。モデルを使ったDB操作をしなくてもバリデーションは理解できるのでシンプルに習得していきましょう!

フォームリクエストバリデーション

ここで扱うバリデーションは「フォームリクエストバリデーション」というものです。

バリデーションを実装する方法として、一番かんたんなのは、直接コントローラに記述するというものですが、 コントローラの見通しが悪くなるので、コントローラにバリデーションは書かず、フォームリクエスト機構を使って、分離しましょう。

専用のフォームリクエストクラスを作成

まず、app/Http/配下にRequestsディレクトリを作成します。 このディレクトリ内に各モデルのバリデーション用クラスを作成していきます。

今回は店舗なので以下のようなファイルを作成します。

app/Http/Requests/StoreRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;

class StoreRequest extends FormRequest
{
public function authorize()
{
return true;
}
// ここにバリデーション内容を記述する
public function rules()
{
return [
'name' => 'required',
];
}
// 各パラメータの表示名を記述する
public function attributes() {
return [
'name' => '店舗名',
];
}
}

 バリデーションルールについて

最初はnameのみをチェックするようにしました。

'name' = 'required'とすることで、入力フォームからのリクエストで、nameの値が入力されているかチェックできます。 このrequiredというものが、バリデーションルールとなります。requiredは未入力かどうかをチェックします。 この他にも、数字や文字列かどうかをチェックしたり、文字数制限チェックなども行えますよ〜。

公式HPに利用出来るルール一覧が載っていますので覗いてみてください(バリデーション 5.6 Laravel)。

フォームリクエストバリデーションを使う

先程作成した、Store用フォームリクエストクラスをコントローラに読み込んであげましょう。

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\StoreRequest; // 作成したクラスを読み込む
class StoreController extends Controller
{
// 登録画面の表示
public function index()
{
return view('stores/index');
}
// 登録処理
public function create(StoreRequest $req) // Reuqestではなく、StoreRequestと記述
{
dd($req-all());
}
}

これでだけで終わりです。 とても簡単でしょう?

実際に店舗登録画面を開いて、名前入力フォームには何も入力せず送信を押してみてください。

「なにも起こりません」

次に、名前入力フォームに「なにかしら」入力して送信するとどうでしょう? リクエストの情報が画面に表示されたかと思います。

何が起こったか?

実は「名前入力フォームに」なにも入力しなかった時、「何も起こらない」のではなく、 きちんとバリデーションチェックが行われています。

流れとしてはこうです。

  • フォームから送信
  • StoreRequestがバリデーションチェック
  • namaの値をみて、値がなければ変数にエラーを入れて元のページにリダイレクト
  • この時コントローラのcreate()メソッド内の処理は実行されない

「変数にエラーを...」と言いましたが、元のページにリダイレクトされたということは、 元のページは登録画面なので、この登録画面内でエラーが入った変数が使えるということになります。

エラーの内容を表示してみる

ビューのフォームの上辺りに以下の記述をしてみてください。

resources/views/stores/index.blade.php
@if($errors)
@foreach($errors->all() as $error)
{{ $error }}
@endforeach
@endif
<form method="POST" action="/stores">
名前: <input type="text" name="name"><br>
メール: <input type="email" name="email"><br>
住所: <input type="text" name="address"><br>
電話: <input type="text" name="tel"><br>
店舗情報: <textarea name="text"></textarea><br>
{{ csrf_field() }}
<input type="submit">
</form>

そして、もう一度登録画面で何も入力せずに送信ボタンを押してください。

エラーメッセージが表示されていると思います。

まず、$errorsにエラーが入っている事を確認し、$errors->all()とすることで、すべてのエラーを取得できます。 あとはそのエラーを一つずつ取り出して表示しているということですね。

今回はnameだけチェックしましたが、StoreRequestクラスにtelやaddressなども追加することで 全パラメータのバリデーションチェックが行えるので是非試してみてください。

※今回エラーが英語となっていますが、日本語化する方法はまた後日紹介します。とても簡単です。

2018/11/21