Laravel5のカスタムバリデーション

Laravelは舶来品なので日本語にはデフォルトで対応していないので日本語入力に関連するバリデーションがないのです。ここではひらがな入力のみを受け付けるバリデーションのカスタマイズをしてみます。
Laravelの自前のバリデーション機能はとても良くできているのでこれを継承して使うのがベストです。いろんなやり方がありますが今回はサービスプロバイダーを作成してどこでも使えるようにしておきます。

  • Laravel5.5
  • php7.1

artisanでプロバイダー作成

artisanコマンドでプロバイダーを作成します。

php artisan make:provider ValidatorServiceProvider

app/Providers/ValidatorServiceProvider.phpというのが作成されるので、boot()の設定だけします。

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use app\Library\CustomValidator; //←これ追加

class ValidatorServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
                // ↓これ追加
        \Validator::resolver(function ($translator, $data, $rules, $messages) {
            return new CustomValidator($translator, $data, $rules, $messages);
        });
    }

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

作成したらプロバイダーに登録します。

//config/app.php
'providers' => [
    ...
    App\Providers\ValidatorServiceProvider::class,
    ...

ここまでだとCustomValidator()っていうクラスがないと叱られるので新規でクラスを作成します。または、bootstrap/cache/services.phpに書き込み権限がないと言われるかもしれません。適切なパーミッションを与えてあげます。
これはどこからでも使えるクラスにした方がいいのでLaravel5 共通クラス(汎用関数)をつくるを参考にしてください。
今回は、app/Library/CustomValidator.phpを作成します。composer.jsonに登録するのを忘れずに。
CustomValidator.phpに実際のカスタムバリデーションを書きます。

<?php
namespace app\Library;

class CustomValidator extends \Illuminate\Validation\Validator
{

      public function validateKana($attribute, $value, $parameters)
    {
        if (mb_strlen($value) > 100) {
            return false;
        }

        if (preg_match('/[^ぁ-んー]/u', $value) !== 0) {
            return false;
        }
        return true;
    }
}

100文字以上でひらがなじゃなかったらエラーという単純なものです。
これでカスタムバリデーションがすでに使えるようになっていますが、エラーの検知だけできる状態でエラーメッセージが出ません。なのでまずはエラーメッセージを日本語化します。

//resources/lang/ja/validation.php
return [
   ...
   'kana' => ':attributeはひらがなで入力をしてください。',
   ...
   'attributes' => [
       ...
        'fkana' => 'ふりがな(せい)',
        'gkana'  => 'ふりがな(めい)',
       ...
   ],

これでエラーメッセージが出るようになります。
アトリビュートがデフォルトでは英語になってしまうので、アトリビュートも設定しておきます。
あとは利用するコントローラ内で、

....
$this->validate($request, [
    'fkana' => 'required|kana',
    'gkana' => 'required|kana',
]);
....

こんな感じで設定します。
この「kana」っていうバリデーションなのですが、これ何に紐付いているのかというと、CustomValidatorクラスで設定しているvalidateKana()のことなんですね。
Laravelのおもしろいところでもあるのですが、メソッドのキャメルケースの後ろ側の文字列、つまり(validate)Kanaを拾っているんです。ややこしいですね。
hiraganaにする場合は、validateHiragana()にするというのが楽ということになってました。

複数のフィールドをバリデーションする

電話番号なんかが3つのフィールドに分かれていたりするわけですが、Laravelのバリデーションターゲットは基本的には「1つのフィールド=1つのエラーメッセージ」です。なので、ちょっと工夫しないと3つのフィールドがある場合は3つのエラーが出てしまいます。

$this->validate($request, [
....
    'tel1' => 'required|regex:/[0-9]/|max:6',
    'tel2' => 'required|regex:/[0-9]/|max:6',
    'tel3' => 'required|regex:/[0-9]/|max:6',
....
]);

3つのフィールドに適当なバリデーションを設定します。
それから3つのどれかにエラーがあったときにはエラーメッセージを表示するというようなことをすればOKです。

<!--  エラーメッセージ重複対応-->
@if($errors->has('tel1'))
    <p class="fm-item__err">{{ $errors->first('tel1') }}</p>
@elseif($errors->has('tel2'))
    <p class="fm-item__err">{{ $errors->first('tel2') }}</p>
@elseif($errors->has('tel3'))
    <p class="fm-item__err">{{ $errors->first('tel3') }}</p>
@endif

https://qiita.com/komatzz/items/c64c83a004b7f2c63ce6

Last update: 2018.01.25 (木)