Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Creating Custom Validation Rules in Laravel

When you validate a Laravel request, built-in rules such as required and string cover many checks. A custom rule class lets you define a check those rules do not express clearly and reuse it in other validations. Laravel runs the custom rule alongside the built-in rules and adds its failure message to the usual validation errors.

Laravel passes the field name and value to the rule class, along with a callback function the rule calls to report an error. Use a class when you want to reuse a check or give a larger check a clear name. A small check used once can stay in a closure.

Create a rule class

Generate a rule class with Artisan, Laravel’s command-line tool:

php artisan make:rule Uppercase

Laravel places the class in app/Rules, creating that directory if necessary. In Laravel 13.x, a generated rule implements ValidationRule and defines a validate method. Laravel passes the method the field name, its value, and a callback that adds an error when the rule fails, as shown in the Laravel validation documentation.

<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class Uppercase implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (! is_string($value)) {
            return;
        }

        if (strtoupper($value) !== $value) {
            $fail('The :attribute must be uppercase.');
        }
    }
}

The type check prevents strtoupper from receiving a value it cannot handle. In this example, the rule is paired with Laravel’s string rule, which reports a type error; the custom rule returns without adding a second error for a non-string value.

Add the rule to request validation

A rule class does not inspect incoming requests by itself. Pass an instance in the rules array for the field you want Laravel to check:

use App\Rules\Uppercase;

$validated = $request->validate([
    'name' => ['required', 'string', new Uppercase],
]);

Laravel checks the field’s rules during request validation. If validation succeeds, $request->validate() returns the validated data. If a rule fails, Laravel throws a validation exception and returns the appropriate response: a redirect for a traditional web request, or a JSON response with a 422 status for an XHR request, which a browser script sends in the background. You can also use the same rule object in the rules method of a Form Request, a request class that organizes validation rules and authorization.

If your code creates a validator directly, pass the rule object in the rules array for Validator::make($data, $rules). Laravel documents these request and validator entry points.

Choose a class for reusable or substantial checks

A rule class gives a check a name you can use in multiple rule arrays and keeps more involved logic in its own file. For example, a project can use one Uppercase rule wherever a field must contain uppercase text. A closure suits a brief check used only once. Laravel describes closures as an option for custom checks used once and rule objects as the reusable form.

There is no strict complexity threshold for choosing between them. Choose a class when reuse, a clear name, or the amount of logic makes the check easier to understand outside the request definition. Keep a short condition inline when moving it to a class would add little clarity.

Decide how missing and empty values should behave

Laravel skips ordinary validation rules, including custom rules, when a field is missing or contains an empty string. A format check alone does not require the field. Add required when the request must include a value.

If the custom rule itself must run for a missing or empty field, generate an implicit rule:

php artisan make:rule RuleName --implicit

Laravel’s documentation explains that an implicit rule marks the field as required, while the rule’s own logic determines whether a missing or empty value fails. Decide whether to put the requirement in a separate required rule or in the custom rule, then make that behavior explicit.

Match the rule API to your Laravel version

The code above uses the ValidationRule interface and its validate method, as documented for current Laravel releases. Older Laravel examples may use a different interface: Laravel 9.x documentation, for example, describes InvokableRule with an __invoke method. Check the documentation for the version installed in your project before copying a rule signature from an older example.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *