Skip to main content
Back to packages
176 GitHub stars

SanderMuller/laravel-fluent-validation

View on GitHub

Description

Fluent and extremely fast validation for Laravel

Write Laravel validation rules with IDE autocompletion instead of memorizing string syntax. Each rule type exposes only the methods that apply to it: FluentRule::string() won't offer digits(), FluentRule::date() won't offer mimes(). each() and children() keep parent and child rules in one place instead of scattered across dot-notation keys. For large arrays, the HasFluentRules trait makes wildcard validation up to 160x faster.

// Before
'name' => 'required|string|min:2|max:255',
'email' => ['required', 'email', Rule::unique('users')->ignore($id)],
'role' => Rule::when($isAdmin, 'required|string|in:admin,editor'),
'items' => 'array',
'items.*.id' => 'required|integer|exists:items,id',
'items.*.name' => 'required|string|max:255',
 
// After
'name' => FluentRule::string('Full Name')->required()->min(2)->max(255),
'email' => FluentRule::email('Email')->required()->unique('users', 'email', fn ($r) => $r->ignore($id)),
'role' => FluentRule::string()->when($isAdmin, fn ($r) => $r->required()->in(['admin', 'editor'])),
'items' => FluentRule::array()->each([
'id' => FluentRule::integer()->required()->exists('items', 'id'),
'name' => FluentRule::string()->required()->max(255),
]),

Performance

Type starters

Laravel's Rule FluentRule equivalent
Rule::string() FluentRule::string()
Rule::numeric() FluentRule::numeric() / FluentRule::integer()
Rule::date() FluentRule::date()
Rule::dateTime() FluentRule::dateTime()
Rule::email() FluentRule::email()
Rule::file() FluentRule::file()
Rule::imageFile($allowSvg) FluentRule::image()->allowSvg() (or just image())
Rule::array($keys = null) FluentRule::array($keys)
Rule::dimensions([...]) FluentRule::image()->minWidth(...)->ratio(...)

Set membership and value spaces

Laravel's Rule FluentRule equivalent
Rule::in([...]) ->in([...]) (on any typed builder)
Rule::notIn([...]) ->notIn([...])
Rule::contains([...]) FluentRule::array()->contains(...)
Rule::doesntContain([...]) FluentRule::array()->doesntContain(...)
Rule::enum(Status::class) FluentRule::enum(Status::class) / ->enum(...)
Rule::anyOf([...]) FluentRule::anyOf([...])

Database lookups

Laravel's Rule FluentRule equivalent
Rule::unique('users')->where(...) ->unique('users', 'col', fn ($r) => $r->where(...))
Rule::exists('roles')->where(...) ->exists('roles', 'col', fn ($r) => $r->where(...))

Conditional callables

Laravel's Rule FluentRule equivalent
Rule::when($cond, $rules, $default) ->when($cond, fn ($r) => …, fn ($r) => …)
Rule::unless($cond, $rules, $default) ->when(! $cond, …)
Rule::requiredIf(fn () => …) ->requiredIf(fn () => …)
Rule::requiredUnless(fn () => …) ->requiredUnless(fn () => …)
Rule::excludeIf(fn () => …) ->excludeIf(fn () => …)
Rule::excludeUnless(fn () => …) ->excludeUnless(fn () => …)
Rule::prohibitedIf(fn () => …) ->prohibitedIf(fn () => …)
Rule::prohibitedUnless(fn () => …) ->prohibitedUnless(fn () => …)

Iteration

Laravel's Rule FluentRule equivalent
Rule::forEach(fn ($v, $k) => …) FluentRule::array()->each(FluentRule::string()->…)

Authorization (escape hatch only)

Laravel's Rule FluentRule equivalent
Rule::can('ability', …$args) ->rule(['can', 'ability', …$args])

FluentRule additions with no Laravel equivalent

Method What it does
->each([key => FluentRule, …]) Co-locate wildcard child rules
->children([key => FluentRule, …]) Co-locate fixed-key child rules
->label('Full Name') Replaces :attribute in messages
->message('…') / ->messageFor('…', '…') Per-rule custom messages
->fieldMessage('…') Field-level fallback message
->whenInput(fn ($input) => …) Branch on full input at validation time

Related Content on Laravel Daily

Video

Recent Courses on Laravel Daily

[NEW] Next.js Basics for Laravel Developers

11 lessons
58 min

How to Build Laravel 13 API From Scratch

30 lessons
1 h 23 min

How to Structure Laravel 13 Projects

16 lessons
1 h 32 min read

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.