How to Use Multiple Custom Rules from laravel-validate in a Laravel Request

You can combine any number of custom rules from the milwad-dev/laravel-validate package by instantiating the rule classes directly in a Form Request's rules() method or by using string-based validation when using_container is enabled in the config.

The milwad-dev/laravel-validate package provides dozens of pre-built validation rules for common patterns like phone numbers, UUIDs, and strong passwords. When building complex Laravel applications, you often need to validate several custom fields simultaneously within a single request class.

Architecture Overview of laravel-validate Rules

Each rule in the package lives in src/Rules/ and implements Laravel's Illuminate\Contracts\Validation\Rule interface. The LaravelValidateServiceProvider (located at src/LaravelValidateServiceProvider.php) handles registration. When the using_container config option is set to true, the provider automatically iterates over all files in src/Rules and registers them with the Validator facade:

$rules = File::files(__DIR__.'/Rules');
foreach ($rules as $rule) {
    $className = 'Milwad\\LaravelValidate\\Rules\\'.$rule->getBasename('.php');
    Validator::extend(
        $rule->getFilenameWithoutExtension(),
        fn($attr,$value,$params,$validator) => (new $className($params))->passes($attr,$value)
    );
}

This architecture allows you to use the rules either as instantiated objects or as strings, depending on your configuration preference.

The most explicit and flexible approach is to import the rule classes and instantiate them in your Form Request. This method works regardless of the using_container setting and allows you to pass constructor arguments (such as country codes for phone validation).

Complete Form Request Example

Below is a practical implementation combining ValidPhoneNumber, ValidUuid, and ValidStrongPassword in a single RegisterUserRequest:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Milwad\LaravelValidate\Rules\ValidPhoneNumber;
use Milwad\LaravelValidate\Rules\ValidUuid;
use Milwad\LaravelValidate\Rules\ValidStrongPassword;

class RegisterUserRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            
            // Validates Iranian phone numbers via constructor argument
            'phone' => [
                'required',
                new ValidPhoneNumber('IR'),
            ],
            
            // Ensures the reference ID is a valid UUID
            'ref_id' => [
                'required',
                new ValidUuid(),
            ],
            
            // Enforces strong password policy (upper, lower, digit, special)
            'password' => [
                'required',
                'string',
                'min:8',
                new ValidStrongPassword(),
            ],
        ];
    }
}

In this example, ValidPhoneNumber accepts a country code parameter that routes to the appropriate callback defined in src/Utils/CountryPhoneCallback.php. The ValidUuid class (located at src/Rules/ValidUuid.php) validates UUID v4 strings, while ValidStrongPassword (at src/Rules/ValidStrongPassword.php) checks for character diversity.

Method 2: String-Based Validation with Container Registration

If you prefer the traditional Laravel string syntax and have enabled using_container in config/laravel-validate.php, the service provider automatically registers rule names that match the class names. This allows you to use pipe-delimited validation strings:

public function rules(): array
{
    return [
        'phone'    => 'required|ValidPhoneNumber:IR',
        'ref_id'   => 'required|ValidUuid',
        'password' => 'required|min:8|ValidStrongPassword',
    ];
}

The LaravelValidateServiceProvider maps these strings to the underlying classes through the extension callback shown in the architecture section. Parameters after the colon (such as IR) are passed to the rule's constructor.

Key Implementation Details

Country-Specific Validation Callbacks

The ValidPhoneNumber and ValidLandlineNumber rules rely on dynamic callbacks for country-specific formatting. These are managed by src/Utils/CountryPhoneCallback.php and src/Utils/CountryLandlineCallback.php, which map country codes to validator classes. When you pass 'IR' to ValidPhoneNumber, the rule delegates validation to the Iranian phone validator registered in the callback utility.

Rule Class Structure

All custom rules implement Illuminate\Contracts\Validation\Rule, ensuring compatibility with Laravel's validator. The package source shows consistent patterns across src/Rules/ValidUuid.php, src/Rules/ValidStrongPassword.php, and src/Rules/ValidPhoneNumber.php: each defines a passes() method for logic and a message() method for error text, with translation keys supporting localization.

Summary

  • Instantiate directly for maximum flexibility and constructor arguments; this works regardless of configuration settings.
  • Enable using_container in config/laravel-validate.php to use string-based validation syntax like ValidPhoneNumber:IR.
  • Combine freely with native Laravel rules (required, email, min:8) in any Form Request.
  • Reference the source in src/Rules/, src/LaravelValidateServiceProvider.php, and src/Utils/ for implementation details.

Frequently Asked Questions

Can I use laravel-validate rules without enabling the container?

Yes. You can instantiate the rule classes directly in your Form Request's rules() method using the new keyword. This approach bypasses the container registration entirely and allows you to pass constructor arguments, such as country codes for phone validation.

How do I pass parameters to custom rules when using string syntax?

When using_container is enabled, append parameters after a colon in the validation string. For example, ValidPhoneNumber:IR passes IR as the constructor argument to the ValidPhoneNumber class. Multiple parameters can be separated by commas if the rule supports them.

Are the validation messages translatable?

Yes. All rule classes in src/Rules/ implement the message() method to return translation keys. The package publishes language files that you can customize, allowing you to localize error messages for ValidStrongPassword, ValidUuid, and other rules according to your application's locale.

Which Laravel versions are supported by milwad-dev/laravel-validate?

The package supports modern Laravel versions that use the Illuminate\Contracts\Validation\Rule interface. The service provider and rule implementations are compatible with Laravel 8.x through 11.x, utilizing standard validation contracts that have remained consistent across recent releases.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →