【Laravel】バリデーション独自ルールの作成方法

Laravelでバリデーション独自ルールを作成することがあったため備忘録。


# Ruleクラスを継承したクラスを作成する

App\Rules配下にルールのクラスを作成します。

下記のコマンドを実行

```
php artisan make:rule {ルール名}
```

例）

```
php artisan make:rule Phone
```

実行すると下記のようなファイルが作成されます。

```Phone.php
<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Phone 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()
    {
        //
    }
}
```

# ルールの作成

作成したファイルにルールを追加します。
`passes()`にはバリデーション判定のルールを返すよう記載し、


```Phone.php
    public function passes($attribute, $value)
    {
        //
    }
```
passes()の引数
`$attribute` にはフィールド名、
`$value` にはそのフィールドの値が入っています。

今回の例では電話番号のチェックを行いたいため、下記のように設定します。

```Phone.php
    public function passes($attribute, $value)
    {
        return preg_match('/^[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}$/', $value);
    }
```

`message()`にはエラーメッセージを記載します。

```Phone.php
    public function message()
    {
        return '正しい電話番号を入力してください。';
    }
```

下記のように記載することもできます。

```Phone.php
    public function message()
    {
        return trans('validation.phone');
    }
```

この場合は言語ファイルにメッセージを追加する必要があります。

```resources/lang/ja/validation.php
    'phone' => '正しい:attributeを入力してください。',

'attributes' => [
    'phone' => '電話番号',
```

# 独自ルールを使う

作成したルールをフォームリクエストで使用してみます。

```UserRequest.php
use App\Rules\Phone;
 
public function rules()
{
    return [
        'phone' => ['required', new Phone], 
    ];
}

```
作成したルールのオブジェクトを呼び出すことで使用できます。
|で記載することはできません。

---

# サービスプロバイダーに記述する

上記で作成したルールでは、|でバリデーションルールを記載できません。
そのため、|で記載したい場合はサービスプロバイダーに記述します。

## サービスプロバイダーに設定する

作成したルールが使用できるよう、AppServiceProviderに設定します。

```AppServiceProvider.php 
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::extend('phone', 'App\Rules\PhoneRule@passes');
    }
}

```

`boot()`内で上記のように記載します。
`Validator::extend()`の第一引数はフォームリクエストで使用する際のルール名となります。


## サービスプロバイダーに直接記載する方法

上記で記載したルールを作成する方法をせずに、サービスプロバイダーに記載することでルールが作成できます。


```AppServiceProvider.php 

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::extend('phone', function ($attribute, $value, $parameters, $validator) {
            return preg_match('/^[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}$/', $value);
        });
    }
}

```

# ルールを使用する
上記で作成・設定したルールを使用します。
作成したルールをフォームリクエストで使用してみます。

```UserRequest.php
public function rules()
{
    return [
        'phone' => 'required|phone', 
    ];
}

```
上記のように｜で記載できます。