Laravelでは必須項目やメールアドレス形式などよく使われるようなバリデーションルールは標準で用意されているので、いつでも簡単に利用することができます。
しかし、標準で数多くのバリデーションルールが用意されていますが、全てを網羅しているわけではなく、独自でバリデーションルールをカスタマイズして適用したい場合もあるでしょう。
この記事ではカスタムバリデーションを作成し、適用する方法を紹介していきたいと思います。
また、下記の記事ではフォームリクエストを使ってバリーでションを行う方法を紹介しているので、ぜひ参考にしてくださいね。
Providerを使ってカスタムバリデーションを実装する
今回はひらがなのバリデーションルールを開発しながら、Providerを使ってカスタムバリデーションを実装する方法を解説していきましょう。
サービスプロバイダ作成
まずはコマンドでサービスプロバイダのファイルを作成していきます。
$ php artisan make:provider ValidatorServiceProvider
カスタムバリデーションルールを実装する
コマンドで作成した直後のValidatorServiceProvider.phpファイルは下記のような状態です。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ValidatorServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
//
}
}
registerメソッドとbootメソッドが準備されています。
registerメソッドには該当のサービスプロバイダをサービスコンテナに登録する際に利用します。
bootメソッドにはサービスプロバイダが全て読み込まれた後に実行されます。
今回はregisterメソッドでサービスコンテナに登録することはせずに、bootメソッドにカスタムバリデーションの処理を実装していきます。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;
class ValidatorServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
// ひらがな
Validator::extend('hiragana', function ($attribute, $value, $parameters, $validator) {
return preg_match('/^[ぁ-ん]+/u', $value);
});
}
}
Validatorファサードを利用してカスタムバリデーションを実装していきます。
extendクラスメソッドの第1引数にはバリデーション適用時に使用する名前を指定します。今回はひらがなのバリデーションルールなので、hiraganaとしましょう。
第2引数にはクロージャを指定し、クロージャの中でバリデーションを行う処理を記述します。
クロージャの戻り値としてtrueを返せばバリデーションを通ります。falseを返すとバリデーションエラーとなります。
$valueにバリデーション対象の値が渡ってくるのでこの変数を使ってpreg_matchメソッドで正規表現での一致を精査しています。
サービスプロバイダを登録する
サービスプロバイダでの実装が完了したら、アプリケーションで利用できるようにサービスプロバイダを登録しましょう。
サービスプロバイダの登録はconfig/app.phpで行います。
<?php
return [
... 略 ...
'providers' => [
... 略 ...
App\Providers\ValidatorServiceProvider::class,
],
];
カスタムバリデーションルールを適用する
実装したカスタムバリデーションを適用するには、Laravelが用意しているバリデーションルールを適用する際と同じように指定してあげることで適用することができます。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SampleRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|hiragana',
];
}
}
またバリデーションエラー時のメッセージはresources/lang/ja/validation.phpで設定することができます。
'hiragana' => ':attributeはひらがなで入力してください。',
ルールオブジェクトを使ってカスタムバリデーションを実装する
ここではカタカナのバリデーションルールを開発しながら、ルールオブジェクトを使ってカスタムバリデーションを実装する方法を解説していきましょう。
ルールオブジェクト作成
コマンドでルールオブジェクトのファイルを作成しましょう。
$ php artisan make:rule KatakanaRule
カスタムバリデーションルールを実装する
コマンドで生成した直後のルールオブジェクトは下記のような状態です。
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class KatakanaRule implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
//
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The validation error message.';
}
}
__constructのコンストラクタメソッドでインスタンス生成時に引数で値を取得することができます。
passesメソッドにバリデーションルールの処理を実装していきます。戻り値としてtrueを返すことでバリデーションが通ったことを示します。falseを返すことでバリデーションエラーとなります。
messagesメソッドにはバリデーションエラー時のメッセージを定義することができます。
それではカタカナのバリデーションルールを実装していきましょう。
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class KatakanaRule implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return preg_match('/[ァ-ヴー]+/u', $value);
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return ':attributeはひらがなで入力してください。';
}
}
サービスプロバイダで実装した時と同様に$valueにバリデーション対象の値が渡されるので、その変数を使ってpreg_matchメソッドの正規表現でカタカナかどうかの精査を行なっています。
カスタムバリデーションルールを適用する
ルールオブジェクトを使ったカスタムバリデーションルールを適用する際は必ず配列で指定する必要があります。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use App\Rules\KatakanaRule;
class SampleRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => ['required', new KatakanaRule],
];
}
}
ルールオブジェクトを使ったカスタムバリデーションの場合、サービスプロバイダを使った場合に比べて登録したりする手間がなくシンプルに作成して適用するだけで実装できるのがメリットですね。
まとめ
Laravelでカスタムバリデーションを実装する方法を解説してきました。
カスタムバリデーションとして独自のバリデーションを実装することで1ヶ所だけでなく、複数ヶ所にバリデーションルールを適用できるので共通化できるのもメリットですね。
日本語のバリデーションは標準のバリデーションルールでは用意されていないので、この記事を参考にしてカスタムバリデーションを実装できるようしておきましょう。