Creating Custom Validation Rules

If validation rules that come with Laravel are not enough for you, then you can create your own validation rules. How awesome is that!



Introduction

This is a tutorial that I wanted to write for a very long time.

The reason why I didn't is because I couldn't imagine a single rule that could be beneficial and does not already come with Laravel.

Are you ready?

In this tutorial, we will create a custom validation rule for:

if($number % 2 == 0) return true;

$number being the value passed in the request, and 2 being the parameter that we want to divide it by.

The % operator computes the remainder after dividing its first operand by its second.

The above code will return true if the remainder equals zero.

This would be the desired end syntax for our validation rule:

$this->validate($request, [
    'number' => 'required|numeric|mod:2'
]);

P.S. If you want to learn more about standard Validation, there are a couple of tutorials on this site that cover that topic:

Hack all day, hack all night

Let's begin.

There are two ways of registering custom validation rules:

  1. Using the extend method on the Validator facade
  2. Using the extendImplicit method on the Validator facade

The extendImplicit method enables you to run your custom validation rule on a empty attribute (The value is null). By default, rules are not executed on attributes that have a value of null. We won't be needing this for this tutorial, but it is good to know.

Both extend and extendImplicit methods support two ways of registering rules:

Using a Closure

Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});

or

Passing a class and method

Validator::extend('foo', 'FooValidator@validate');

For this tutorial we will use a Closure.

Using a Closure

Validator::extend('foo', function ($attribute, $value, $parameters, $validator) {
    return $value == 'foo';
});

The custom validator Closure 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.

So to modify the code above to our needs we will want to do:

\Validator::extend('mod', function ($attribute, $value, $parameters, $validator) {
    return $value % $parameters[0] == 0;
});

Great! Now paste the above code to your app/Providers/AppServiceProvider@boot method.

Validate this!

You can use our newly created validation rule from your controller methods, like so:

$this->validate($request, [
    'number' => 'required|numeric|mod:2'
]);

or from your routes/web.php routes file, like so:

Route::get('/', function (\Illuminate\Http\Request $request) {
    $validator = \Validator::make($request->all(), [
        'number' => 'required|numeric|mod:2'
    ]);

    if($validator->fails())
    {
        return $validator->errors();
    }

    return "Validation passed!!";
});

Defining the error message

To provide a pretty error message for our custom validation rule, you should add:

"mod" => "Your input was invalid!",

to the first level of the array in resources/lang/en/validation.php.


You can see the whole code for this tutorial on GitHub. Or just the code for this tutorial here.

Thank you for reading! Let me know if you have any other examples for this tutorial in the comments bellow.

Sources

Comments