PHPackages                             sandermuller/laravel-fluent-validation - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. sandermuller/laravel-fluent-validation

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

sandermuller/laravel-fluent-validation
======================================

Fluent validation rule builders for Laravel

0.2.2(today)17↑2900%MITPHPPHP ^8.2CI passing

Since Apr 3Pushed todayCompare

[ Source](https://github.com/SanderMuller/laravel-fluent-validation)[ Packagist](https://packagist.org/packages/sandermuller/laravel-fluent-validation)[ Docs](https://github.com/sandermuller/laravel-fluent-validation)[ GitHub Sponsors](https://github.com/SanderMuller)[ RSS](/packages/sandermuller-laravel-fluent-validation/feed)WikiDiscussions main Synced today

READMEChangelog (7)Dependencies (22)Versions (8)Used By (0)

Fluent validation rule builders for Laravel
===========================================

[](#fluent-validation-rule-builders-for-laravel)

[![Latest Version on Packagist](https://camo.githubusercontent.com/30c501606d58181f86a04096a7e030b55d6d40d0ee6fcc57de05283280aef697/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f73616e6465726d756c6c65722f6c61726176656c2d666c75656e742d76616c69646174696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/sandermuller/laravel-fluent-validation)[![GitHub Tests Action Status](https://camo.githubusercontent.com/ec4c87ad2415a65e37b651ca2b0085be1490b18d38d1839786d3b21933f9eb6d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f73616e6465726d756c6c65722f6c61726176656c2d666c75656e742d76616c69646174696f6e2f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/sandermuller/laravel-fluent-validation/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/9f4cb5560c8da94035acf229ef15647fa76ac44a3c8961a02782a54fb30149ae/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f73616e6465726d756c6c65722f6c61726176656c2d666c75656e742d76616c69646174696f6e2f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/sandermuller/laravel-fluent-validation/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)

Type-safe, fluent validation rule builders for Laravel. Write validation rules with full IDE autocompletion instead of memorizing string syntax. Validates large arrays **up to 77x faster** than native Laravel.

```
// Before
['name' => 'required|string|min:2|max:255']

// After
['name' => FluentRule::string('Full Name')->required()->min(2)->max(255)]
```

Installation
------------

[](#installation)

```
composer require sandermuller/laravel-fluent-validation
```

Requires PHP 8.2+ and Laravel 11+.

Quick start
-----------

[](#quick-start)

The simplest way to use FluentRule is anywhere you'd normally write validation rules. Let's start with `Validator::make()`:

```
use SanderMuller\FluentValidation\FluentRule;

$validated = Validator::make($request->all(), [
    'name'  => FluentRule::string('Full Name')->required()->min(2)->max(255),
    'email' => FluentRule::email('Email')->required(),
    'age'   => FluentRule::numeric('Age')->nullable()->integer()->min(0),
])->validate();
```

When you pass a label like `'Full Name'`, it automatically replaces `:attribute` in all error messages for that field. You get "The Full Name field is required" instead of "The name field is required". No separate `attributes()` array needed.

### In a Form Request

[](#in-a-form-request)

You may use FluentRule in Form Requests exactly as you would string rules:

```
use Illuminate\Foundation\Http\FormRequest;
use SanderMuller\FluentValidation\FluentRule;
use SanderMuller\FluentValidation\HasFluentRules;

class StorePostRequest extends FormRequest
{
    use HasFluentRules;

    public function rules(): array
    {
        return [
            'title'    => FluentRule::string('Title')->required()->min(2)->max(255),
            'body'     => FluentRule::string()->required(),
            'email'    => FluentRule::email('Email')->required()->unique('users'),
            'date'     => FluentRule::date('Publish Date')->required()->afterToday(),
            'agree'    => FluentRule::boolean()->accepted(),
            'avatar'   => FluentRule::image()->nullable()->max('2mb'),
            'tags'     => FluentRule::array(label: 'Tags')->required()->each(
                              FluentRule::string()->max(50)
                          ),
            'password' => FluentRule::password()->required()->mixedCase()->numbers(),
        ];
    }
}
```

These rule objects implement Laravel's `ValidationRule` interface. They work in Form Requests, `Validator::make()`, `Rule::forEach()`, and `Rule::when()`.

### Gradual adoption

[](#gradual-adoption)

You don't need to convert all your rules at once. Fluent rules mix freely with string rules and native rule objects in the same array:

```
$rules = [
    'name'   => FluentRule::string()->required()->min(2)->max(255),  // fluent
    'email'  => 'required|string|email|max:255',               // string, still works
    'role'   => ['required', LaravelRule::in(['admin', 'user'])],  // array, still works
];
```

### Relationship with Laravel's `Rule` class

[](#relationship-with-laravels-rule-class)

`FluentRule` is intentionally named differently from `Illuminate\Validation\Rule` so both can be used without aliasing. You generally don't need Laravel's `Rule` at all:

Laravel's `Rule`FluentRule equivalent`Rule::forEach(fn () => ...)``FluentRule::array()->each(...)``Rule::when($cond, $rules, $default)``->when($cond, fn ($r) => ..., fn ($r) => ...)``Rule::unique('users')``FluentRule::string()->unique('users')``Rule::exists('roles')``FluentRule::string()->exists('roles')``Rule::in([...])``FluentRule::string()->in([...])``Rule::enum(Status::class)``FluentRule::string()->enum(Status::class)``Rule::anyOf([...])``FluentRule::anyOf([...])`Why this package?
-----------------

[](#why-this-package)

**Better DX.** IDE autocompletion for every rule. No more guessing `required_with` vs `required_with_all`, or whether it's `digits_between` or `digitsBetween`. The method names tell you.

**Type-safe rule combinations.** Each rule type only exposes methods that make sense for it. `FluentRule::string()` doesn't have `digits()`, `FluentRule::numeric()` doesn't have `alpha()`. Incompatible combinations like `required|string|digits:5` become impossible. Your IDE catches them before you run a single test.

**Inline error messages.** Labels and per-rule messages live right next to the rules they belong to. No more maintaining a separate `messages()` array that drifts out of sync.

**77x faster array validation.** For large arrays (imports, bulk operations), `RuleSet::validate()` bypasses Laravel's O(n²) wildcard expansion and validates per-item with compiled fast-checks. [See benchmarks.](#benchmarks)

Error messages
--------------

[](#error-messages)

### Labels

[](#labels)

Pass a label to the factory method and every error message automatically uses it as the `:attribute` name:

```
return [
    'name'  => FluentRule::string('Full Name')->required()->min(2)->max(255),
    'email' => FluentRule::email('Email Address')->required(),
    'age'   => FluentRule::numeric('Your Age')->nullable()->integer()->min(0),
    'items' => FluentRule::array(label: 'Import Items')->required()->min(1),
];
// "The Full Name field is required."
// "The Email Address field must be a valid email address."
// "The Import Items field must have at least 1 items."
```

Labels work in Form Requests, `Validator::make()`, and `RuleSet::validate()`. You may also set a label after construction using `->label('Name')`.

### Per-rule messages

[](#per-rule-messages)

You may attach a custom error message to the most recently added rule using `->message()`:

```
FluentRule::string('Full Name')
    ->required()->message('We need your name!')
    ->min(2)->message('At least :min characters.')
    ->max(255)
```

Labels and messages compose naturally. Labels improve ALL error messages for the field, while `->message()` overrides specific rules. For a field-level fallback that applies to any failure, use `->fieldMessage()`:

```
FluentRule::string()->required()->min(2)->fieldMessage('Something is wrong with this field.')
```

> **Note:** Standard Laravel `messages()` arrays and `Validator::make()` message arguments still work and take priority over `->message()` and `->fieldMessage()`.

Array validation with `each()` and `children()`
-----------------------------------------------

[](#array-validation-with-each-and-children)

When validating arrays of items, you may define the rules for each item inline using `each()`:

```
// Scalar items: each tag must be a string under 255 characters
FluentRule::array()->each(FluentRule::string()->max(255))

// Object items: each item has named fields
FluentRule::array()->required()->each([
    'name'  => FluentRule::string('Item Name')->required(),
    'email' => FluentRule::string()->required()->rule('email'),
    'qty'   => FluentRule::numeric()->required()->integer()->min(1),
])

// Nested arrays
FluentRule::array()->each([
    'items' => FluentRule::array()->each([
        'qty' => FluentRule::numeric()->required()->min(1),
    ]),
])
```

`each()` works both standalone (passed directly to a validator) and through `RuleSet`. When used through `RuleSet`, wildcard expansion is automatically optimized for better performance on large datasets.

### Fixed-key children with `children()`

[](#fixed-key-children-with-children)

For objects with known keys (not wildcard arrays), you may use `children()` to co-locate the child rules with the parent:

```
// Instead of:
'search'       => FluentRule::array()->required(),
'search.value' => FluentRule::string()->nullable(),
'search.regex' => FluentRule::string()->nullable()->in(['true', 'false']),

// Write:
'search' => FluentRule::array()->required()->children([
    'value' => FluentRule::string()->nullable(),
    'regex' => FluentRule::string()->nullable()->in(['true', 'false']),
]),
```

`children()` produces fixed paths (`search.value`), while `each()` produces wildcard paths (`items.*.name`). Both may be used together on the same array when needed.

`children()` is also available on `FluentRule::field()` for untyped fields with known sub-keys. You may combine it with `rule()` for polymorphic fields (e.g., `FluentRule::field()->rule(FluentRule::anyOf(...))->children([...])`).

Performance
-----------

[](#performance)

Laravel's wildcard validation (`items.*.name`) has [known O(n²) performance issues](https://github.com/laravel/framework/issues/49375) for large arrays. This package solves them.

### Benchmarks

[](#benchmarks)

ScenarioNative LaravelRuleSet::validate()Speedup500 items, 7 fields (string, numeric, date, boolean, in)~165ms~2.1ms**77x**100 items, 47 fields with `exclude_unless`~3,000ms~76ms**40x**### How it works

[](#how-it-works)

`RuleSet::validate()` applies three optimizations automatically. You don't need to configure anything:

OptimizationWhat it doesSpeedup**Per-item validation**Reuses one small validator per item instead of one giant validator for all items**~40x** for complex rules**Compiled fast-checks**Compiles string rules to native PHP closures, skipping Laravel entirely for valid items**~77x** for simple rules**Conditional rule rewriting**Rewrites `exclude_unless` references to relative paths for per-item contextEnables per-item for real-world validators### How to use it

[](#how-to-use-it)

**Option 1: `RuleSet::validate()` for inline validation:**

```
$validated = RuleSet::from([
    'items' => FluentRule::array()->required()->each([
        'name' => FluentRule::string('Item Name')->required()->min(2),
    ]),
])->validate($request->all());
```

**Option 2: `HasFluentRules` trait for Form Requests:**

```
use SanderMuller\FluentValidation\HasFluentRules;

class ImportRequest extends FormRequest
{
    use HasFluentRules;

    public function rules(): array
    {
        return [
            'items' => FluentRule::array()->required()->each([
                'name'  => FluentRule::string('Item Name')->required()->min(2),
                'email' => FluentRule::string('Email')->required()->rule('email'),
            ]),
        ];
    }
}
```

> **Note:** Without `RuleSet` or `HasFluentRules`, rules work normally through Laravel's built-in validation. You just won't get the performance optimization for wildcards.

Benchmarks run automatically on PRs via GitHub Actions.

RuleSet
-------

[](#ruleset)

`RuleSet` provides a structured way to define and validate complete rule sets. You may create one from an array of rules or build it fluently:

```
use SanderMuller\FluentValidation\RuleSet;

// From an array
$validated = RuleSet::from([
    'name'  => FluentRule::string('Full Name')->required()->min(2)->max(255),
    'email' => FluentRule::email('Email')->required(),
    'items' => FluentRule::array()->required()->each([
        'name'  => FluentRule::string()->required()->min(2),
        'price' => FluentRule::numeric()->required()->min(0),
    ]),
])->validate($request->all());

// Or fluently, with conditional fields and merging
$validated = RuleSet::make()
    ->field('name', FluentRule::string('Full Name')->required())
    ->field('email', FluentRule::email('Email')->required())
    ->when($isAdmin, fn (RuleSet $set) => $set
        ->field('role', FluentRule::string()->required()->in(['admin', 'editor']))
        ->field('permissions', FluentRule::array()->required())
    )
    ->merge($sharedAddressRules)
    ->validate($request->all());
```

`when()` and `unless()` are available via Laravel's `Conditionable` trait. `merge()` accepts another `RuleSet` or a plain array.

MethodReturnsDescription`RuleSet::from([...])``RuleSet`Create from a rules array`RuleSet::make()->field(...)``RuleSet`Fluent builder`->merge($ruleSet)``RuleSet`Merge another RuleSet or array into this one`->when($cond, $callback)``RuleSet`Conditionally add fields (also: `unless`)`->toArray()``array`Flat rules with `each()` expanded to wildcards`->validate($data)``array`Validate with full optimization (see [Performance](#performance))`->prepare($data)``PreparedRules`Expand, extract metadata, compile. For custom Validators`->expandWildcards($data)``array`Pre-expand wildcards without validating`RuleSet::compile($rules)``array`Compile fluent rules to native Laravel format### Using with custom Validators

[](#using-with-custom-validators)

If you extend `Illuminate\Validation\Validator` directly (e.g., for import jobs), extend `FluentValidator` instead. It handles the full pipeline automatically:

```
use SanderMuller\FluentValidation\FluentValidator;

class JsonImportValidator extends FluentValidator
{
    public function __construct(array $data, protected ?User $user = null)
    {
        parent::__construct($data, $this->buildRules());
    }

    private function buildRules(): array
    {
        return [
            '*.type' => FluentRule::string()->required()->in(InteractionType::cases()),
            '*.end_time' => FluentRule::numeric()
                ->requiredUnless('*.type', ...InteractionType::withoutDuration())
                ->greaterThanOrEqualTo('*.start_time'),
        ];
    }
}
```

`FluentValidator` resolves the translator and presence verifier from the container, calls `prepare()` on the rules, and sets implicit attributes. No manual wiring needed.

> **Note:** When rules reference other fields using wildcards (e.g., `requiredUnless('*.type', ...)`), `FluentValidator` and `HasFluentRules` handle this automatically. Standalone FluentRule objects self-validate in isolation and can't resolve cross-field wildcard references.

> **Tip:** For validators with many cross-field references using a dynamic prefix, a simple helper reduces repetition:
>
> ```
> protected function ref(string ...$parts): string
> {
>     return $this->prefix . '*.' . implode('.', $parts);
> }
>
> // Then: ->excludeUnless($this->ref('type'), ...) instead of
> //       ->excludeUnless($this->prefix . '*.' . ExternalInteraction::TYPE, ...)
> ```

---

Rule reference
--------------

[](#rule-reference)

### String

[](#string)

Validate string values with length, pattern, format, and comparison constraints:

```
FluentRule::string()->min(2)->max(255)->between(2, 255)->exactly(10)
FluentRule::string()->alpha()->alphaDash()->alphaNumeric()  // also: alpha(ascii: true)
FluentRule::string()->regex('/^[A-Z]+$/')->notRegex('/\d/')
FluentRule::string()->startsWith('prefix_')->endsWith('.txt')  // also: doesntStartWith(), doesntEndWith()
FluentRule::string()->lowercase()->uppercase()
FluentRule::string()->url()->uuid()->ulid()->json()->ip()->macAddress()->timezone()->hexColor()
FluentRule::string()->confirmed()->currentPassword()->same('field')->different('field')
FluentRule::string()->inArray('values.*')->inArrayKeys('values.*')->distinct()
```

### Email

[](#email)

Validate email addresses with configurable strictness:

```
FluentRule::email()->rfcCompliant()->strict()->validateMxRecord()->preventSpoofing()
FluentRule::email()->withNativeValidation(allowUnicode: true)
FluentRule::email()->required()->unique('users', 'email')
```

> **Tip:** `FluentRule::string()->email()` is also available if you prefer keeping email as a string modifier.

### Password

[](#password)

Validate password strength with readable, chainable requirements:

```
FluentRule::password(min: 12)->letters()->mixedCase()->numbers()->symbols()->uncompromised()
```

### Numeric

[](#numeric)

Validate numbers with type, size, digit, and comparison constraints:

```
FluentRule::numeric()->integer(strict: true)->decimal(2)->min(0)->max(100)->between(1, 99)
FluentRule::numeric()->digits(4)->digitsBetween(4, 6)->minDigits(3)->maxDigits(5)->multipleOf(5)
FluentRule::numeric()->greaterThan('field')->lessThan('field')  // also: greaterThanOrEqualTo(), lessThanOrEqualTo()
```

### Date

[](#date)

Validate dates with boundaries, convenience shortcuts, and format control. All comparison methods accept `DateTimeInterface|string`:

```
FluentRule::date()->after('today')->before('2025-12-31')->between('2025-01-01', '2025-12-31')
FluentRule::date()->afterToday()->future()->nowOrPast()  // also: beforeToday(), todayOrAfter(), past(), nowOrFuture()
FluentRule::date()->format('Y-m-d')->dateEquals('2025-06-15')
FluentRule::dateTime()->afterToday()                     // shortcut for format('Y-m-d H:i:s')
```

### Boolean

[](#boolean)

Validate boolean values and acceptance/decline:

```
FluentRule::boolean()->accepted()->declined()
FluentRule::boolean()->acceptedIf('role', 'admin')->declinedIf('type', 'free')
```

### Array

[](#array)

Validate arrays with size constraints, structure requirements, and allowed keys:

```
FluentRule::array()->min(1)->max(10)->between(1, 5)->exactly(3)->list()
FluentRule::array()->requiredArrayKeys('name', 'email')
FluentRule::array(['name', 'email'])  // restrict allowed keys
FluentRule::array(MyEnum::cases())    // BackedEnum keys
```

### File

[](#file)

Validate uploaded files with size and type constraints. Size methods accept integers (kilobytes) or human-readable strings:

```
FluentRule::file()->max('5mb')->between('1mb', '10mb')
FluentRule::file()->extensions('pdf', 'docx')->mimes('jpg', 'png')->mimetypes('application/pdf')
```

### Image

[](#image)

Validate images with dimension constraints. Inherits all file methods:

```
FluentRule::image()->max('5mb')->allowSvg()
FluentRule::image()->minWidth(100)->maxWidth(1920)->minHeight(100)->maxHeight(1080)
FluentRule::image()->width(800)->height(600)->ratio(16 / 9)
```

### Field (untyped)

[](#field-untyped)

When a field needs modifiers but no type constraint, you may use `FluentRule::field()`:

```
FluentRule::field()->present()
FluentRule::field()->requiredIf('type', 'special')
FluentRule::field('Answer')->nullable()->in(['yes', 'no'])
```

### AnyOf

[](#anyof)

Validate that a value passes at least one of the given rule sets (Laravel's `Rule::anyOf` equivalent):

```
FluentRule::anyOf([
    FluentRule::string()->required()->min(2),
    FluentRule::numeric()->required()->integer(),
])
```

### Embedded rules

[](#embedded-rules)

String, numeric, and date rules support embedded Laravel rule objects for `in`, `unique`, `exists`, and `enum`. Both `in()` and `notIn()` accept either an array of values or a `BackedEnum` class:

```
FluentRule::string()->in(['draft', 'published'])
FluentRule::string()->in(StatusEnum::class)          // all enum values
FluentRule::string()->notIn(DeprecatedStatus::class)
FluentRule::string()->enum(StatusEnum::class)
FluentRule::string()->unique('users', 'email')
FluentRule::string()->exists('roles', 'name')
```

### Field modifiers

[](#field-modifiers)

All rule types share common modifiers for controlling field presence, prohibition, and exclusion:

```
// Presence
->required()  ->nullable()  ->sometimes()  ->filled()  ->present()  ->missing()

// Conditional presence: accepts field references or Closure|bool
->requiredIf('role', 'admin')  ->requiredUnless('type', 'guest')  ->requiredIf(fn () => $cond)
->requiredWith('field')  ->requiredWithAll('a', 'b')  ->requiredWithout('field')  ->requiredWithoutAll('a', 'b')

// Prohibition & exclusion
->prohibited()  ->prohibitedIf('field', 'val')  ->prohibitedUnless('field', 'val')  ->prohibits('other')
->exclude()  ->excludeIf('field', 'val')  ->excludeUnless('field', 'val')  ->excludeWith('f')  ->excludeWithout('f')

// Messages
->label('Name')  ->message('Rule-specific error')  ->fieldMessage('Field-level fallback')

// Other
->bail()  ->rule($stringOrObjectOrArray)  ->whenInput($condition, $then, $else?)
```

> **Note:** `exclude` rules only affect `validated()` output when placed at the outer validator level. To exclude a field from validated data, place `exclude` alongside the fluent rule: `'field' => ['exclude', FluentRule::string()]`

### Conditional rules

[](#conditional-rules)

All rule types use Laravel's `Conditionable` trait, so you may conditionally apply rules using `when()`:

```
FluentRule::string()->required()->when($isAdmin, fn ($r) => $r->min(12))->max(255)
```

For data-dependent conditions that need to inspect the input at validation time, you may use `whenInput()`:

```
FluentRule::string()->whenInput(
    fn ($input) => $input->role === 'admin',
    fn ($r) => $r->required()->min(12),
    fn ($r) => $r->sometimes()->max(100),
)
```

The condition closure receives the full input as a `Fluent` object and is evaluated during validation, not at build time. You may also pass string rules instead of closures: `->whenInput($condition, 'required|min:12')`.

### Escape hatch

[](#escape-hatch)

You may add any Laravel validation rule via `rule()`. Accepts strings, objects, and array tuples:

```
FluentRule::string()->rule('email:rfc,dns')
FluentRule::string()->rule(new MyCustomRule())
FluentRule::file()->rule(['mimetypes', ...$acceptedTypes])
```

### Macros

[](#macros)

Macros let you create reusable rule chains that can be shared across fields and files:

```
// In a service provider
NumericRule::macro('percentage', fn () => $this->integer()->min(0)->max(100));
StringRule::macro('slug', fn () => $this->alpha(true)->lowercase());

// Then use anywhere
FluentRule::numeric()->percentage()
FluentRule::string()->slug()
```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Sander Muller](https://github.com/sandermuller)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

42

—

FairBetter than 89% of packages

Maintenance100

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 56.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

7

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/abeb7bd51fd77656b4133bdcdf4eca99cc8b495b83ca72f63674ff15f2b72a39?d=identicon)[SanderMuller](/maintainers/SanderMuller)

---

Top Contributors

[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (388 commits)")[![SanderMuller](https://avatars.githubusercontent.com/u/9074391?v=4)](https://github.com/SanderMuller "SanderMuller (46 commits)")[![mvdnbrk](https://avatars.githubusercontent.com/u/802681?v=4)](https://github.com/mvdnbrk "mvdnbrk (46 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (32 commits)")[![Nielsvanpach](https://avatars.githubusercontent.com/u/10651054?v=4)](https://github.com/Nielsvanpach "Nielsvanpach (23 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (20 commits)")[![pforret](https://avatars.githubusercontent.com/u/474312?v=4)](https://github.com/pforret "pforret (16 commits)")[![sebastiandedeyne](https://avatars.githubusercontent.com/u/1561079?v=4)](https://github.com/sebastiandedeyne "sebastiandedeyne (14 commits)")[![AlexVanderbist](https://avatars.githubusercontent.com/u/6287961?v=4)](https://github.com/AlexVanderbist "AlexVanderbist (12 commits)")[![patinthehat](https://avatars.githubusercontent.com/u/5508707?v=4)](https://github.com/patinthehat "patinthehat (10 commits)")[![riasvdv](https://avatars.githubusercontent.com/u/3626559?v=4)](https://github.com/riasvdv "riasvdv (10 commits)")[![AdrianMrn](https://avatars.githubusercontent.com/u/12762044?v=4)](https://github.com/AdrianMrn "AdrianMrn (8 commits)")[![crynobone](https://avatars.githubusercontent.com/u/172966?v=4)](https://github.com/crynobone "crynobone (8 commits)")[![irfanm96](https://avatars.githubusercontent.com/u/42065936?v=4)](https://github.com/irfanm96 "irfanm96 (5 commits)")[![thecaliskan](https://avatars.githubusercontent.com/u/13554944?v=4)](https://github.com/thecaliskan "thecaliskan (5 commits)")[![IGedeon](https://avatars.githubusercontent.com/u/694313?v=4)](https://github.com/IGedeon "IGedeon (4 commits)")[![abenerd](https://avatars.githubusercontent.com/u/7523903?v=4)](https://github.com/abenerd "abenerd (3 commits)")[![jessarcher](https://avatars.githubusercontent.com/u/4977161?v=4)](https://github.com/jessarcher "jessarcher (3 commits)")[![koossaayy](https://avatars.githubusercontent.com/u/6431084?v=4)](https://github.com/koossaayy "koossaayy (3 commits)")[![lloricode](https://avatars.githubusercontent.com/u/8251344?v=4)](https://github.com/lloricode "lloricode (3 commits)")

---

Tags

laravelvalidationfluentrule-builder

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/sandermuller-laravel-fluent-validation/health.svg)

```
[![Health](https://phpackages.com/badges/sandermuller-laravel-fluent-validation/health.svg)](https://phpackages.com/packages/sandermuller-laravel-fluent-validation)
```

###  Alternatives

[propaganistas/laravel-phone

Adds phone number functionality to Laravel based on Google's libphonenumber API.

3.0k35.7M100](/packages/propaganistas-laravel-phone)[proengsoft/laravel-jsvalidation

Validate forms transparently with Javascript reusing your Laravel Validation Rules, Messages, and FormRequest

1.1k2.3M48](/packages/proengsoft-laravel-jsvalidation)[axlon/laravel-postal-code-validation

Worldwide postal code validation for Laravel and Lumen

3853.3M1](/packages/axlon-laravel-postal-code-validation)[watson/validating

Eloquent model validating trait.

9723.3M46](/packages/watson-validating)[wendelladriel/laravel-validated-dto

Data Transfer Objects with validation for Laravel applications

759569.4k13](/packages/wendelladriel-laravel-validated-dto)[laravel-validation-rules/credit-card

Validate credit card number, expiration date, cvc

2412.2M4](/packages/laravel-validation-rules-credit-card)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
