スタイル・エッジ技術ブログ

士業集客支援/コンサルティングのスタイル・エッジのエンジニアによるブログです。

Laravelのカスタムバリデーションでもパラメータを渡したい!

f:id:styleedge_tech:20191007101412j:plain
フリー写真素材ぱくたそ

こんにちは!スタイル・エッジLABOのやっすんです。

Laravelでバリデーションを実装するとき、 「max:256」のように、呼び出したバリデーションの後ろにコロンでパラメータを渡すことがありますよね。
今日はLaravelのカスタムバリデーションでもこのようなパラメータを渡せるようにする方法をご紹介します。
なお、Laravelのバージョンは5.5、PHPのバージョンは7.1で実装しています。

カスタムバリデーションの作り方

ファイル構成
—app
 ∟Providers
  ∟ValidatorServiceProvider.php
 ∟Validator
  ∟ CustomValidator.php (このファイルはapp配下なら使いやすい場所に格納して構いません)
—config
 ∟app.php
—resources
 ∟lang
  ∟ja
   ∟validation.php
(1)カスタムバリデーションを実装するクラスを作成する。

 この記事ではクラス名をCustomValidatorとします。

// \Illuminate\Validation\Validatorを継承するのを忘れずに!
<?php
class CustomValidator extends \Illuminate\Validation\Validator
{
    /**
     * CustomValidator constructor.
     * @param Translator $translator
     * @param array $data
     * @param array $rules
     * @param array $messages
     * @param array $customAttributes
     */
    public function __construct(
        Translator $translator,
        array $data,
        array $rules,
        array $messages = [],
        array $customAttributes = []
    ) {
        parent::__construct($translator, $data, $rules, $messages, $customAttributes);
    }
?>
(2)サービスプロバイダを作成する

 この記事ではクラス名をValidatorServiceProviderとします。

<?php
class ValidatorServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::resolver(function($translator, array $data, array $rules, array $messages, array $customAttributes) {
            // (1)で作成したクラスのインスタンスを返却します
            return new CustomValidator($translator, $data, $rules, $messages, $customAttributes);
        });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}
?>

 作成したサービスプロバイダは忘れずにconfig/app.phpの「providers」に追加してあげましょう。

<?php
return [
    // 前略
    'providers' => [
        // 省略
        App\Providers\ValidatorServiceProvider::class,
    ],
    // 後略
];
?>
(3)CustomValidatorクラス内にカスタムバリデーションメソッドを実装する。

 この記事では「validateHogehoge()」というメソッド名で実装します。
 「validateHogehoge」なら「hogehoge」、「validateHogeFuga()」なら「hoge_fuga」で呼び出し&使用することができます。

<?php
class CustomValidator extends \Illuminate\Validation\Validator
{
    /**
     * CustomValidator constructor.
     * @param Translator $translator
     * @param array $data
     * @param array $rules
     * @param array $messages
     * @param array $customAttributes
     */
    public function __construct(
        Translator $translator,
        array $data,
        array $rules,
        array $messages = [],
        array $customAttributes = []
    ) {
        parent::__construct($translator, $data, $rules, $messages, $customAttributes);
    }

    public function validateHogehoge($attribute, $value, $parameters)
    {
        // バリデーション処理内容
    }
?>

カスタムバリデーションのエラーメッセージにパラメータを反映させる

(1)CustomValidatorの__construct()内で、メソッドごとにパラメータ置換の処理を実装します。
<?php
class CustomValidator extends \Illuminate\Validation\Validator
{
    /**
     * CustomValidator constructor.
     * @param Translator $translator
     * @param array $data
     * @param array $rules
     * @param array $messages
     * @param array $customAttributes
     */
    public function __construct(
        Translator $translator,
        array $data,
        array $rules,
        array $messages = [],
        array $customAttributes = []
    ) {
        parent::__construct($translator, $data, $rules, $messages, $customAttributes);

        // validateHogehogeのパラメータ置換
        $this->addReplacer('hogehoge'(※バリデーション名), function($message, $attribute, $rule, $parameters) {
            return str_replace(':max'(※バリデーションメッセージ内でパラメータの値に置換する文字列), $parameters[0], $message);
        });
    }

    public function validateHogehoge($attribute, $value, $parameters)
    {
        // バリデーションに渡したいパラメータの数が合っているか確認
        $this->requireParameterCount(1(※渡したいパラメータの数), $parameters, 'hogehoge'(バリデーション名));

         // バリデーション処理内容
        // 渡したパラメータの値は$parameters[0]で使うことができます。
    }
?>

 なお、複数のパラメータを渡したい場合(最大値と最小値を両方渡したい場合など)は、
 ①AddReplacer()内のstr_replace()の第一引数と第二引数を配列にする。
 ②バリデーションメソッド内でrequireParameterCount()の第一引数を渡すパラメータの数にする
 でOKです!

<?php
    /**
     * CustomValidator constructor.
     * @param Translator $translator
     * @param array $data
     * @param array $rules
     * @param array $messages
     * @param array $customAttributes
     */
    class CustomValidator extends \Illuminate\Validation\Validator
    {
        public function __construct(
            Translator $translator,
            array $data,
            array $rules,
            array $messages = [],
            array $customAttributes = []
        ) {
            parent::__construct($translator, $data, $rules, $messages, $customAttributes);

            // validateFugafugaのパラメータ置換
            $params = [
                ':min',
                ':max',
            ];
            $this->addReplacer('fugafuga', function($message, $attribute, $rule, $parameters) {
                return str_replace($params, $parameters, $message);
            });
        }

        public function validateFugafuga($attribute, $value, $parameters)
        {
            // バリデーションに渡したいパラメータの数が合っているか確認
            $this->requireParameterCount(2(※渡したいパラメータの数), $parameters, 'fugafuga');
    
            // バリデーション処理内容
            // 渡したパラメータの値は渡した順に$parameters[0]、$parameters[1]...で使うことができます。
        }
?>
(2)resources/lang/ja/validation.phpにカスタムバリデーション用のエラーメッセージを実装する。
<?php
return [
    // 前略

    /*
     * ↓カスタムバリデーションメッセージ
     */
    'hogehoge'              => ':attributeは:max以下の数値を指定してください。',
    'fugafuga'              => ':attributeは:min以上:max以下の数値を指定してください。',

    // 後略
];
?>

最後に

スタイル・エッジLABOでは、一緒に働く仲間を募集しています。
もし興味を持っていただけましたら、ぜひ採用サイトものぞいてみてください!

recruit.styleedge-labo.co.jp