# How to Extend laravel-validate with New Custom Rules: A Complete Guide

> Learn to extend laravel-validate with new custom rules. Create a PHP class implementing the Rule contract and register it for seamless validation in your Laravel applications.

- Repository: [Milwad Khosravi/laravel-validate](https://github.com/milwad-dev/laravel-validate)
- Tags: how-to-guide
- Published: 2026-03-07

---

**You can extend laravel-validate by creating a PHP class in `src/Rules` that implements `Illuminate\Contracts\Validation\Rule`, then optionally enabling container-based registration in [`config/laravel-validate.php`](https://github.com/milwad-dev/laravel-validate/blob/main/config/laravel-validate.php) to reference the rule by its snake-case filename.**

The milwad-dev/laravel-validate package provides a robust collection of reusable validation rules for Laravel applications. When you need domain-specific validation logic that the built-in rules don't cover, you can extend laravel-validate with new custom rules following the package's established conventions. This guide demonstrates the exact implementation patterns used in [`src/Rules/ValidStrongPassword.php`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Rules/ValidStrongPassword.php) and the registration mechanism found in `LaravelValidateServiceProvider`.

## Creating a Custom Rule Class

All validation rules in laravel-validate reside in the `src/Rules` directory. To add your own, create a new PHP class that implements `Illuminate\Contracts\Validation\Rule` and defines two required methods: `passes($attribute, $value)` and `message()`.

### Rule Class Structure

The `passes` method receives the attribute name and value, returning `true` for valid input. The `message` method returns a translation key for the error message. Here is a complete example following the package's pattern:

```php
<?php

namespace Milwad\LaravelValidate\Rules;

use Illuminate\Contracts\Validation\Rule;

class ValidEvenNumber implements Rule
{
    /**
     * Determine if the validation rule passes.
     */
    public function passes($attribute, $value): bool
    {
        return is_int($value) && $value % 2 === 0;
    }

    /**
     * Get the validation error message.
     */
    public function message(): string
    {
        return __('validate.even-number');
    }
}

```

Store this file at [`src/Rules/ValidEvenNumber.php`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Rules/ValidEvenNumber.php). The class name uses **PascalCase** while the filename uses snake-case when referenced as a string later.

## Enabling Container-Based Registration

By default, laravel-validate can automatically register every rule class found in `src/Rules` using Laravel's service container. This allows you to reference rules by their snake-case filename rather than instantiating objects.

Enable this feature in [`config/laravel-validate.php`](https://github.com/milwad-dev/laravel-validate/blob/main/config/laravel-validate.php):

```php
'using_container' => true,

```

When `LaravelValidateServiceProvider` boots, it scans the `src/Rules` directory and registers each rule automatically (see lines 75-88 in the source). If you modify this config, run `php artisan config:cache` or republish the config using:

```bash
php artisan vendor:publish --tag=laravel-validate-config

```

## Using Your Custom Rule

Laravel-validate supports two syntaxes for applying custom rules, depending on whether you enabled container registration.

### Method 1: Object Instantiation (Always Available)

Regardless of the `using_container` setting, you can instantiate the rule class directly in your validation arrays:

```php
use Milwad\LaravelValidate\Rules\ValidEvenNumber;

$request->validate([
    'quantity' => ['required', new ValidEvenNumber],
]);

```

### Method 2: String Syntax (Requires Container Registration)

When `using_container` is enabled, reference the rule by its snake-case filename:

```php
$request->validate([
    'quantity' => 'required|valid_even_number',
]);

```

Both approaches integrate seamlessly with Laravel's validator and work in Form Request classes.

## Adding Translation Files

Custom rules should return translation keys from the `message()` method to support localization. Create or edit language files in `resources/lang/<locale>/validate.php`:

```php
return [
    'even-number' => 'The :attribute must be an even number.',
];

```

To publish the package's existing language files for reference, use the provider's publish tags:

```bash
php artisan vendor:publish --tag=validate-lang-en

```

## Manually Registering Rules (Advanced Alternative)

If you prefer not to rely on the container-based auto-discovery in `LaravelValidateServiceProvider`, you can manually extend Laravel's validator in your own service provider's `boot` method:

```php
use Illuminate\Support\Facades\Validator;
use Milwad\LaravelValidate\Rules\ValidEvenNumber;

Validator::extend('valid_even_number', function ($attribute, $value, $parameters, $validator) {
    return (new ValidEvenNumber)->passes($attribute, $value);
});

```

This approach bypasses the `using_container` configuration entirely while still leveraging your custom rule logic.

## Summary

- Create rule classes in `src/Rules` implementing `Illuminate\Contracts\Validation\Rule` with `passes()` and `message()` methods
- Enable `'using_container' => true` in [`config/laravel-validate.php`](https://github.com/milwad-dev/laravel-validate/blob/main/config/laravel-validate.php) to use snake-case string references
- Validate using either `new ValidEvenNumber` (object) or `'valid_even_number'` (string)
- Store translations in `resources/lang/<locale>/validate.php` using keys returned by `message()`
- Reference [`src/Rules/ValidStrongPassword.php`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Rules/ValidStrongPassword.php) for the package's canonical implementation pattern

## Frequently Asked Questions

### Do I need to enable container registration to use custom rules?

No. Container registration is optional. You can always instantiate your rule class directly with `new ValidEvenNumber` in validation arrays. The `using_container` setting only enables the convenience of using snake-case strings like `'valid_even_number'` in validation rules.

### What naming convention should I follow for rule classes?

Follow the package's established pattern: use **PascalCase** for class names (e.g., `ValidEvenNumber`) and store the file in `src/Rules/` with a matching name. When using string-based validation, Laravel converts the filename to snake-case automatically (e.g., `valid_even_number`).

### Can I use these custom rules in Form Request classes?

Yes. Both object instantiation and string syntax work inside Form Request classes. Simply import your rule class or use the string identifier in the `rules()` method, exactly as you would in controller-based validation.

### Where should I place custom rules if I'm contributing back to the package?

Place contribution candidates directly in `src/Rules/` following the structure of existing rules like [`ValidStrongPassword.php`](https://github.com/milwad-dev/laravel-validate/blob/main/ValidStrongPassword.php). Ensure your class implements the `Rule` contract and includes appropriate translation keys in the package's language files under `resources/lang/`.