Skip to content

Posts › Development

Development

Create a custom validation rule with string alias

In this tutorial I will show how to define a Laravel validation rule providing a custom alias string to use in custom validation classes.

3 min read
Create a custom validation rule with string alias

In this tutorial I will show how to define a Laravel validation rule providing a custom alias string to use in custom
validation classes.

Here, the problem is the following. As the documentation states, you can make a new validation rule by launching the
artisan command

shell
 1php artisan make:rule Uppercase

This will create the file app/Rules/Uppercase with the
following structure:

php
 1<?php
 2
 3namespace App\Rules;
 4
 5use Closure;
 6use Illuminate\Contracts\Validation\ValidationRule;
 7
 8class UpperCase implements ValidationRule
 9{
10    /**
11     * Run the validation rule.
12     *
13     * @param  \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
14     */
15    public function validate(string $attribute, mixed $value, Closure $fail): void
16    {
17        //
18    }
19}

By defining the validate() method you can provide your custom validation logic. For example:

php
 1    /**
 2     * Run the validation rule.
 3     */
 4    public function validate(string $attribute, mixed $value, Closure $fail): void
 5    {
 6        if (strtoupper($value) !== $value) {
 7            $fail('The :attribute must be uppercase.');
 8        }
 9    }

Then, in a custom request you can use it as follows:

php
 1use App\Rules\Uppercase;
 2 
 3$request->validate([
 4    'name' => ['required', 'string', new Uppercase],
 5]);

However, you cannot use a string alias for the rule. So, if you want to define your validation rules as follows:

php
 1use App\Rules\Uppercase;
 2 
 3$request->validate([
 4    'name' => 'required|string|my_uppercase',
 5]);

you cannot use this approach. Fortunately, an alternative one exists, but it is not currently documented.

First, define a custom generic class under app/Validators/UppercaseValidator. Note that the location is arbitrary and
you could use a different one of your choice.

php
 1<?php
 2
 3namespace App\Validators;
 4
 5class UpperCaseValidator
 6{
 7    public function validate($attribute, $value, $parameters, $validator): bool
 8    {
 9        // ToDO
10    }
11}

The validate() methods accepts four arguments:

  • $attribute: the name of the attribute being validated;
  • $value: the value of the attribute being validated;
  • $parameters: an associative array containing any rule parameter, defined after a comma (
    e.g. required|my_rule,foo,baz. Here, foo and baz are parameters)
  • $validator the instance of the current validator.

The method should basically return a boolean value depending on whether the validation passes or fails.

However, this alone is not sufficient. You must instruct the framework about the existence of such validator. For this
purpose, in any loaded service provider, for example AppServiceProvider, you must extend the basic validator as
follows:

php
 1<?php
 2
 3namespace App\Providers;
 4
 5use App\Validators\UppercaseValidator;
 6use Illuminate\Support\Facades\Validator;
 7use Illuminate\Support\ServiceProvider;
 8
 9class AppServiceProvider extends ServiceProvider
10{
11    /**
12     * Register any application services.
13     */
14    public function register(): void
15    {
16        //
17    }
18
19    /**
20     * Bootstrap any application services.
21     */
22    public function boot(): void
23    {
24        Validator::extend('my_uppercase', UppercaseValidator::class);
25    }
26}

Such validator extension requires two parameters:

  • The name of the string alias (here, my_uppercase)
  • The name of the custom validator class (here, App\Validators\UppercaseValidator::class)

Note that your custom rule cannot contain spaces , dashses - or other special characters, but may contain
underscores _.

And that's it! You have your custom validation rule with a string alias.

Don't forget to define (after publishing your language files with php artisan lang:publish), the my_uppercase key
in your lang/<locale>/validation.php language file:

e.g.

php
 1return [
 2   ...
 3   
 4   'my_uppercase' => 'The :attribute must be in uppercase',
 5];