ウェブログラム

実践しながらじっくり学ぶ、Webプログラム習得サイトです。自作サービスの公開までWeb開発を実践していきましょう!

Webrogram

自分のオリジナルサービスを作って運営しよう!

【初心者向け】Laravelのバリデーション入門

Laravel入門記事一覧はこちら webrogram.hatenadiary.jp

ここでは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());
    }
}

ビューについて(登録画面)

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

f:id:iku8:20180903230720p:plain

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>

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

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

f:id:iku8:20180903233340p:plain

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

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

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