Laravelのカスタムバリデーション作成、柔軟性と制御を持ったデータの検証方法

Laravelは人気のあるPHPフレームワークであり、データのバリデーションを簡単に行うための多くのバリデーションルールを提供しています。

Laravelのバリデーション機能は非常に強力で柔軟なのですが、ビジネスロジックに合わせた独自のバリデーションルールを作成する方法も用意されています。

この記事では、執筆時の最新版であるLaravel10系でカスタムバリデーションを作成する方法について解説します。

カスタムバリデーションを実現するために Rule オブジェクトの作成

Laravelが用意しているカスタムバリデーションを作成するにはRuleオブジェクトを作るところから始まります。

今回は誕生日の年をバリデーションさせるものを例に進めていきます。

以下のコマンドで基礎クラスが作成できます

$ php artisan make:rule BirthYearRule

   INFO  Rule [app/Rules/BirthYearRule.php] created successfully.  

$

作成されたファイルの内容はこちら

<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class BirthYearRule implements ValidationRule
{
    /**
     * Run the validation rule.
     *
     * @param  \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
     */
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        //
    }
}

validate関数の中身を変更します

    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if(!($value >= 1980 && $value <= date('Y'))){
            $fail(':attribute は 1980年 ~ '.date('Y').'年の間で入力する必要があります');
        }
    }

これで準備は完了です

Rule オブジェクトの使い方

作成したカスタムバリデーションを使用するにはRuleオブジェクトのインスタンスを渡すことで検証することができます。

use App\Rules\BirthYearRule;

$request->validate([
    'birth_year' => ['required', 'numeric', new BirthYearRule()],
]);

バリデーションルールの required と同様に使用することが可能です。

番外: エラーメッセージの翻訳対応

エラーメッセージを多言語化対応したり、他のバリデーションルールの翻訳設定と同じファイルで管理する場合には以下の記述で翻訳対応することができます。

if(!($value >= 1980 && $value <= date('Y'))){
    $fail('validation.birth_year_rule')->translate([
        'now_year' => date('Y')
    ]);
}

translate メソッドの第1引数でプレースホルダー置換が設定できます。

終わりに

以上、Laravelのカスタムバリデーションの作成方法でした。

他にもバリデーションに関する実務で役立った方法などをまとめた記事を作成したので興味があれば参照してみてください