Laravelのバリデーションの方法3つを改めて確認してみた

Laravel バリデーション方法 Laravel
※当サイトはアフィリエイト広告を掲載しています。

Laravelが用意するバリデーションの方法は、以下の3種類あります。

  1. Illuminate\Http\Requestのvalidateメソッド
  2. Validatorファサード
  3. FormRequest(フォームリクエスト)

この内、私は3を選ぶことが非常に多く、あまり1~2の方法をよく知らないなぁと思いました。これではいかんと、改めて公式マニュアルを読み直し、使い所を考えてみることに。

結論としては一長一短あるなと感じたので、かみ砕いて説明していきます。説明用として、極めて簡単な以下のバリデーションを課題にしたいと思います

  1. name: 文字列で最大32文字
  2. email: メールアドレスの形式で

Illuminate\Http\Requestのvalidateメソッド

主にコントローラー内にて、簡単なバリデーション用に用いるケースが多いと思います。

というのも、Illuminate\Http\Requestクラスはコントローラー内での利用は定番中の定番だから。そのためアッと言う間に記述できます。

コード例

以下のような感じです。

public function store(Request $request): RedirectResponse
{
    // バリデーション実行
    $validated = $request->validate([
      'name' => ['string', 'max:32'],
      'email' => ['email'],
    ]);

    // バリデーション通過(以下省略)

4~7行目にて、Requestクラスのvalidateメソッドでバリデーションを実行。これが失敗(false相当)の場合はIlluminate\Validation\ValidationExceptionという例外を投げます。

言い換えると、バリデーションの結果に応じて以下となります。

  • OKの場合:そのまま何事も無かったかのように処理が続く
  • NGの場合:コントローラーから離れて、エラーを返す(エラー画面を表示するViewを表示等)

ちょっとしたものをバリデーションするにはいいのかもですね。

メリット&デメリット

メリット
  • 簡単に書ける
  • とりあえずすぐ試せる
  • バリデーションNG時、自動的にエラーを返せる(デメリットにもなり得る)
デメリット
  • 複雑な処理を書くには不向き
  • 使い回しに向かない
  • コントローラー内のコードが増える(Fat Controllerに影響)
  • コントローラーにバリデーションの役割が入ってしまう

Validatorファサード

こちらも多くはコントローラー内で使うことになるでしょうか(私はあまり使った記憶がありません)。

Validatorファサードにより、makeメソッドを呼び出しバリデーションを実行します。

「ファサード」とは、スタティックメソッドのように呼び出せるLaravelの機能です。

public function store(Request $request): RedirectResponse
{
    // バリデーション実行
    $validator = Validator::make($request->all(), [
      'name' => ['string', 'max:32'],
      'email' => ['email'],
    ]);

    // バリデーションが通らなかった時の処理(ここではリダイレクト)
    if ($validator->fails()) {
      return redirect('post/create')
        ->withErrors($validator)
        ->withInput();
    }

    // バリデーション通過(以下省略)

Requestクラスのvalidateメソッドでは即座に例外が発生し、NGの場合はコントローラーの処理が中断しました。

対してValidator::make()では処理は止まりません。

返ってきた$validatorオブジェクトのfailsメソッドでバリデーションの可否を得られるので、そこから自分で好きな処理を行えます。

メリット&デメリット

メリット
  • バリデーションNG時も、自分で好きな処理を書ける
デメリット
  • 使い回しに向かない
  • コントローラー内のコードがより増える(Fat Controllerに影響)
  • コントローラーにバリデーションの役割が入ってしまう

基本は、Requestクラスのvalidateメソッドと近いものがありますね。

FormRequestクラス

FormRequestクラスというのは、リクエストに関する処理を記載する事のできるクラスです。Laravelが用意したFormRequestクラスを継承し、独自の設定をすることが可能です。

FormRequestクラスは、通常以下の場所に配置します。

app\Http\Requests

例えばこんな感じです。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ProfileUpdateRequest extends FormRequest
{
  public function rules(): array
  {
    // バリデーションルールを定義
    return [
      'name' => ['string', 'max:32'],
      'email' => ['email'],
    ];
  }
}
<?php

use App\Http\Requests\ProfileUpdateRequest;

// ~略~

class ProfileController extends Controller
{

  // ~略~

  public function store(ProfileUpdateRequest $request): RedirectResponse
  {
    // ここを通る時点で、バリデーションは通っている
  }
}

rulesメソッド内でバリデーションの定義をする。加えてコントローラーで読み込み(この例では12行目)をするだけで、コントローラーの処理開始前にバリデーションを実行してくれます。

バリデーションが通らない場合は、Illuminate\Validation\ValidationExceptionの例外が発生し、コントローラーの処理に移りません。

ですのでこの例では、4行目に到達した時点でバリデーションに通っていることになります。

コントローラーではバリデーションのことに全く気を取られなくて済む。つまりは余計なことに頭を使わなくて済むのでコードも見やすく、便利ですね!

メリット&デメリット

メリット
  • 複雑なバリデーションも書ける
  • 使い回しできる
  • バリデーションの役割を分離できる(保守しやすい)
  • コードが読みやすくなる
デメリット
  • 簡単なバリデーションの場合、ファイル作成の手間と感じることも

まとめ

振り返って見てみると、ウェブアプリケーション開発時のFormRequestの便利さは一番に思います。簡単な説明用だったら、他の方法もありですけどね。

実際にLaravelマニュアルでも、複雑なものは「FormRequestを使え」と書いてあるので、これまで通りを基本にやっていこうと思いました。

しかしながら適所では、他の方法もあることを思い出せればなと思います。

コメント

タイトルとURLをコピーしました