Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Validate Laravel Package

milwad/laravel-validate

Laravel Validate extends Laravel's built-in validation with a large collection of custom rule classes and helper methods, making advanced validation logic simpler and faster to write. Includes localization support and requires PHP 8.0+ and Laravel 9.0+.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and pin the version that matches your Laravel release. The compatibility matrix matters more than the README headline:

composer require milwad/laravel-validate

Then check which line you landed on — 2.0 is the only line supporting Laravel 13, 1.9 for Laravel 12, and so on. Pin it explicitly in composer.json if you are on anything other than the latest Laravel:

"milwad/laravel-validate": "^2.0"

Publish what you need, not everything. The config is only relevant if you plan to use string-style rules; the lang files are only relevant if you want editable messages:

php artisan vendor:publish --tag="laravel-validate-config"
php artisan vendor:publish --tag="validate-lang-en"

First use case — drop a rule into an existing FormRequest. The lowest-friction adoption path is to leave your validation structure untouched and only swap in rule objects where Laravel's built-ins fall short. Phone number is the canonical example:

use Milwad\LaravelValidate\Rules\ValidPhoneNumber;

public function rules(): array
{
    return [
        'phone' => ['required', 'string', new ValidPhoneNumber()],
    ];
}

Where to look first. The docs/1.x/ folder has one markdown file per rule (linked from the README table) — that is the real reference, since each rule has a specific expected format and its own message key. Start there rather than reading the source, then confirm the behaviour with a one-off test on a sample value.

Implementation Patterns

Keep rule objects as the default usage mode. They compose cleanly with Laravel's pipe and array syntax, are type-safe, and are greppable. Use them in FormRequest::rules(), in Validator::make(), and inside Rule::when() / conditional arrays without any ceremony:

'website' => ['nullable', 'url', new ValidDomain()],
'color'   => ['required', 'string', new ValidHexColor()],

Use string-style rules only when the rule set is dynamic or config-driven. With using_container => true in config/laravel-validate.php you can write 'required|ValidPhone'. This is genuinely useful when rules come from a database, a YAML file, or an admin panel — you cannot store new ValidPhoneNumber() in a config array. For static, hand-written rules it just costs you IDE navigation and static analysis.

Treat the package as a supplement, not a replacement. The strongest pattern is layering: let Laravel handle structure (required, string, max:255, email, unique) and let this package handle format semantics it doesn't cover — IBAN, IMEI, hex colour, Discord username, Jalali date, slug/case checks. Don't rewrite working email/url rules.

Use ValidPattern as the escape hatch. When you need something the package doesn't ship and it's a single regex, ValidPattern keeps you inside the rule-object convention instead of scattering regex: strings through your request classes. This also centralises the message in one place.

Centralise custom messages with the published lang file. Once published, the file is a normal Laravel translation file. Override messages by key in lang/{locale}/laravel-validate.php rather than passing :message arrays at every call site — this keeps error copy consistent and makes it a copywriter/translator task instead of a code task.

Test rules the same way you test validation. A ValidNationalCard or ValidIban rule that passes your happy path is not tested; the checksums are where regressions hide. A small Pest dataset per rule covers the real risk cheaply:

it('validates iban', function (string $value, bool $valid) {
    $v = Validator::make(
        ['iban' => $value],
        ['iban' => [new ValidIban()]]
    );

    expect($v->passes())->toBe($valid);
})->with([
    ['IR062960000000100324200001', true],
    ['IR000000000000000000000000', false],
    ['', false],
]);

Mirror the rules on the frontend deliberately. For slug, case, port, and hex colour, clients usually want the same constraint client-side. Document the source-of-truth rule in a shared constants file so the JS regex and the PHP rule don't drift.

Gotchas and Tips

Pinning is non-negotiable here. The Laravel support window is fragmented across minor releases (1.5 vs 1.6 vs 1.9 vs 2.0 support different framework majors). An unpinned composer require combined with a framework upgrade will silently drop you onto a line that doesn't support your Laravel version. Add the constraint to composer.json and let CI catch the mismatch.

using_container => true is a global switch with a wide blast radius. Flip it and every validator in the app now resolves bare strings through the container. If a string rule name ever collides with a custom rule alias you registered via Validator::extend, behaviour depends on resolution order and is painful to debug. Enable it deliberately, ideally only in projects that need dynamic rule sets, and note it in the README of your own app.

Empty strings and null are not the rule's job. Custom rule objects generally assume a non-null value is arriving. Always pair with nullable (or sometimes) so the rule never sees null, and add string before the object rule to avoid type surprises from query params or JSON payloads.

Language files are per-locale tags, and a missing tag fails loudly at publish time. The tag is validate-lang-{$lang} — publishing validate-lang-de for a locale the package doesn't ship produces an error, not a fallback. Check the Support Languages section first, and remember the rule messages may still be missing in your locale even if the framework translations exist.

Regional rules carry domain assumptions you must verify. Several rules are Iran-specific (ValidIranPostalCode, ValidNationalCard, ValidCartNumberIran, ValidJalaliDate, ValidLandlineNumber). Phone and landline rules in particular encode a country's numbering plan. Read the rule's doc page and source before shipping to a multi-country product — a rule named ValidPhoneNumber is not a universal E.164 validator, and that naming invites misuse in code review.

Zero dependents is a real signal, not a dealbreaker. With no downstream packages relying on this code, edge cases are less battle-tested than in Laravel core. Practical mitigation: pin the version, wrap the external-facing rules you depend on in your own thin rule classes or tests, and prefer it for format validation (low blast radius) over anything security-critical like password strength gating on its own.

Debugging failing rules: inspect the message key first. When a valid-looking value fails, the fastest triage is dd($validator->errors()->toArray()) — if you get a raw key like validation.valid_iban instead of a sentence, your lang file isn't published or the locale is unsupported, and you're chasing a translation problem rather than a logic problem. After that, run the exact value against the rule in php artisan tinker.

Extension points are simple by design. The package gives you plain ValidationRule classes, so anything it lacks you add the same way: a class implementing ValidationRule with a $fail() closure, plus a translation key. ValidPattern covers one-off regexes; a custom class covers anything with a checksum or lookup. Contribute it upstream if it's generic — the README explicitly welcomes PRs for new languages and the project is MIT-licensed with a changelog and release history to build on.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table