エンジニ屋.com(エンジニヤドットコム)

分かりやすくを意識して情報発信!

【Laravel】独自のバリデーションを作成する4つの方法【比較】


Laravelで独自のオリジナルのバリデーションルールを作成する場合、 4つの方法で定義することができます。

あの解説記事と、あの記事のバリデーションの書き方が違うぞ?!どっちが正解なんだ?

本記事では、それぞれの書き方の方法とそのメリットを説明します。

具体的に同じバリデーションを比較した方がわかりやすいので、例として、 「値が全て大文字であるかどうか」のバリデーションを比較していきます。

もし値が全て大文字でなければ、エラーを返すルールです。

それでは、見ていきましょう!

コントローラ内に記述

メリット

直接的でシンプル。

特定のアクションや特定のコントローラでのみ使用するような一時的なバリデーションルールに適しています。

実装例

//app\Http\Controllers\Controller.php

public function store(Request $request)
{
    $request->validate([
        'field' => [
            'required',
            function ($attribute, $value, $fail) {
                if (mb_strtoupper($value) !== $value) {
                    $fail('大文字である必要があります');
                }
            },
        ],
    ]);

    // ...
}

コード解説

validateメソッド: $requestオブジェクトのメソッドで、送られてきたリクエストのデータに対するバリデーションルールを適用します。

'field': バリデーションを適用するリクエストのデータのキーとしています。

'required': 'field'が必須であることを示すバリデーションルール。

2つ目に無名関数でカスタムバリデーションロジックを定義しています。

$attribute: バリデーション対象のフィールド名(この場合は'field')。

$value: バリデーション対象のフィールドの値。

mb_strtoupper()はPHPで用意された関数で、入力された文字列を大文字にして、 入力された文字列と比較しています。

$fail: バリデーションエラー時にコールするコールバック関数。

このカスタムルールで、もし$valueが大文字でなければ、エラーメッセージを返します。

FormRequestクラスを使用

メリット

再利用性が高く、バリデーションルールと関連するロジックを1つのクラス内に集約できる。

コントローラがスリムに保たれ、テストも容易になります。

実装例

先ずは、コマンドでファイルを作成します。

php artisan make:request  UppercaseFormRequest

ファイルが作成されたら、rulesメソッド内をController内に書いたように記述します。

// app\Http\Requests\UppercaseFormRequest.php

public function rules()
{
    return [
        'field' => [
            'required',
            function ($attribute, $value, $fail) {
                if (mb_strtoupper($value) !== $value) {
                    $fail('大文字である必要があります');
                }
            },
        ],
    ];
}

Controller内で記述した内容と同じように、配列の2つ目に無名関数で定義できます。

※権限によってバリデーションの有効が必要ない場合は、authorizeメソッドの返り値をtrueに変更しておきましょう。

public function authorize()
    {
        return true;
    }

Service Provider内で定義

メリット

アプリケーション全体で使用できるカスタムバリデーションルールを定義するのに適している。

再利用性が高い。

実装例

// AppServiceProvider.php

public function boot()
{
    Validator::extend('uppercase', function ($attribute, $value, $parameters, $validator) {
        return mb_strtoupper($value) === $value;
    });

    Validator::replacer('uppercase', function ($message, $attribute, $rule, $parameters) {
        return $attribute.' must be uppercase.';
    });
}

コード解説

bootメソッドは、Laravelのサービスプロバイダ内で使用され、サービスコンテナのバインディングや、他の起動時の処理を実行するための場所として提供されています。

Validator::extend: extendメソッドを使って新しいバリデーションルールを定義します。

'uppercase': 新しいバリデーションルールの名前を付けています。

無名関数: バリデーションのロジックを定義するコールバック関数。

この関数は、値がすべて大文字である場合にtrueを返します。

Validator::replacer: replacerメソッドを用いて、特定のバリデーションルールに関連するエラーメッセージのフォーマットを定義します。

'uppercase': メッセージのフォーマットを定義するバリデーションルールの名前。

無名関数: エラーメッセージのフォーマットを定義するコールバック関数。

専用のバリデーションルールクラス

メリット

バリデーションのロジックを独立したクラスに分離できるため、再利用性とテスタビリティが向上します。

複雑なバリデーションロジックや再利用が必要な場合に特に役立ちます。

実装例

先ずば、コマンドを実行してカスタムバリデーションルールのスケルトン(雛形)を生成します。

php artisan make:rule Uppercase

// Uppercase.php

public function passes($attribute, $value)
{
    return mb_strtoupper($value) === $value;
}

public function message()
{
    return ':attribute は大文字である必要があります';
}

利用する際は、ControllerやRequest内で以下のように記述する必要があります。

$request->validate([
    'field' => ['required', new Uppercase],
]);

コード解説

passesメソッドは、属性の値がルールを満たすかどうかを判定します。

この例では、値がすべて大文字であるかをチェックしています。

すべて大文字であればtrueを、そうでなければfalseを返します。

messageメソッドは、バリデーションルールが失敗したときに表示するエラーメッセージを返します。

:attributeプレースホルダは、バリデーションを実行する際の属性名に置き換えられます。

以上です!お疲れ様です。

どの方法を選ぶかは、バリデーションの複雑さや再利用のニーズに応じて決めることができます。

専用のバリデーションルールクラスを使うと、他のLaravelデベロッパーとのコードの共有や、テストのしやすさなどの面でメリットがあります。

最新の記事を公開する際には、X(旧Twitter)でもお知らせしています。
ご興味のある方は、ぜひフォローをお願いいたします!