Get "PHP 8 in a Nuthshell" (Now with PHP 8.4)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

Extending Validator facade for custom validation rules in Laravel

In one of my articles, I’ve explained how you can extend class behavior using macros in Laravel.

So for instance, if you want to add an additional method called makeKebab to Illuminate\Support\Collection class in Laravel, you can use a static macro method like so.

//App\Providers\AppServiceProvider

namespace App\Providers;

use Illuminate\Support\Collection;
use Illuminate\Support\Str;

class AppServiceProvider
{
    public function boot()
    {
        Collection::macro('makeKebab', function () {
            return $this->map(function ($value) {
                return Str::kebab($value);
            });
        });
    }
}

A similar concept can be used to add custom validation rules to the Validator facade by using the extend method.

The extend method

Laravel provides an extend method which can be used on the Validator facade. The extend method is used to register custom validation rules which are available through the entire application.

So, if we want to add a validation rule to check if each word in the attribute must begin with a capital letter, we can extend it like so.

//App\Providers\AppServiceProvider

namespace App\Providers;

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

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Validator::extend('titlecase', function ($attribute, $value, $parameters, $validator) {
            return ucwords($value) === $value;
        });
    }
}

Here, the first parameter of extend is the name of the custom validation rule and the second parameter is the Closure which receives four arguments: the name of the $attribute being validated, the $value of the attribute, an array of $parameters passed to the rule, and the Validator instance.

Using the validation rule

Once defined, the rule can be used while validating request attribute like so.

Validator::make($data, [
    'title' => [
        'required',
        'titlecase',
    ],
]);

Validation message for the rule

You can set a validation message for the custom validation rule using two ways:

  • Using an inline custom message array

In this, you would need to define a validation message within a Request inside messages like so.

public function messages()
{
    return [
        'titlecase' => 'Each word in :attribute must begin with a capital letter'
    ];
}
  • By adding an entry globally in the validation language file such as resources/lang/en/validation.php like so.
return [
    'titlecase' => 'Each word in :attribute must begin with a capital letter',
    ...
    ...
    'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],
];
Learn the fundamentals of PHP 8 (including 8.1, 8.2, 8.3, and 8.4), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article?

Buy me a coffee

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?