Library / SDK
milwad-dev/laravel-validate avatar
milwad-dev/laravel-validate

laravel-validate: custom validation rules for the formats Laravel does not cover

The Laravel-Validate package enhanced Laravel validation capabilities with custom rules and methods for simplified and efficient validation logic

595 stars49 forksPHPMIT

At a glance

What is it?
laravel-validate is a MIT licensed Laravel package that adds a catalogue of rule classes for things like phone numbers, national IDs, plate numbers, crypto addresses and postal codes, with per-language message files and a service container mode for rules that need it.
Who is it for?
Adopt laravel-validate if your Laravel forms validate identifiers that the framework has no rule for, particularly Iranian and other regional formats, and you want the messages localised rather than hand written. Do not adopt it for rules Laravel already ships, since you would be adding a dependency for something the framework does.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 47 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Validation rules for formats the framework has no opinion about

Laravel ships a good set of validation rules, but it stops at the generic ones, and a rule for a national identity number or a car plate does not exist in the framework. laravel-validate fills that gap with a catalogue of rule classes. The project describes itself as enhancing Laravel validation capabilities with custom rules and methods for simplified and efficient validation logic, and the introduction says you can validate data more easily because the package has lots of rule classes. The rules themselves are concrete formats, and the table in the README gives a sample of the range: ValidBase64, ValidBitcoinAddress, ValidCamelCase, ValidCapitalCharWithNumber, ValidCarNumber, and ValidCartNumberIran. The audience is a Laravel developer working on forms where the data is regional or domain specific, and who does not want to write a regex inside a FormRequest and then translate the error message by hand.

Install, publish the config, publish the language files

Installation is one Composer command.

bash
composer require milwad/laravel-validate

Two optional publish steps follow, both driven by Artisan tags. The config file is published with the laravel-validate-config tag.

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

Language files, which hold the validation messages, are published per language with a validate-lang tag where the placeholder is replaced by the language name, for example validate-lang-en.

shell
php artisan vendor:publish --tag="validate-lang-{$lang}"
shell
php artisan vendor:publish --tag="validate-lang-en"

The README points at its support languages section if you are unsure of the language name to use. The repository layout matches this design: a config/ directory for the published config, a lang/ directory for the message catalogues, src/ for the rule classes, docs/ with a per-rule markdown file, and tests/. The PHP requirement is 8.0 or newer and Laravel 9.0 or newer.

The using_container switch changes how rules are resolved

There is one configuration option that determines how the rules are instantiated, and it is worth understanding before you write your validation arrays. The config file ships with using_container set to false, with a comment explaining that if you want to use rules like required|ValidPhone in your validations you can change it to true. With the container enabled, the rule name is resolved through the service container, so a rule such as ValidPhone becomes a class resolved by the container to check the phone number. With it disabled, the rules are used as plain class instances. The default in the shipped config is false, which is the safer starting point, because container resolution means the rule can have constructor dependencies injected rather than being constructed with no arguments. The choice affects every rule you use in the application, so it is a decision to make at install time rather than rule by rule.

Two ways to write a rule in a validation array

With the container mode off, the README shows the straightforward form, where you import the rule class and instantiate it with the new keyword inside your rules array.

php
use Milwad\LaravelValidate\Rules\ValidPhoneNumber;

return [
    'phone' => ['required', new ValidPhoneNumber()],
];

With the container mode on, the same rule is written as a string, and the README's example is a phone_number field with required|ValidPhone.

php
'phone_number' => 'required|ValidPhone',

The string form is more compact and reads like a normal Laravel rule list, which is the point of the option. The instantiation form is more explicit and gives you an autocompleted class reference, and it is the form that works with the default configuration. Either way the rule is a class rather than a closure, so it is testable on its own, and the class is the unit that carries both the validation logic and the message key, which is how the localisation stays attached to the rule.

Localisation is part of the package, not an afterthought

The package supports localisation and can be used for most languages, and when a language is missing the README asks you to open a pull request for a new language or write your own. That is the honest arrangement for a validation library, because the messages are the part that has to be translated, and the checks themselves are usually language independent. The mechanics are the publish command above and the lang/ directory in the repository. The published file is per language and per message, so overriding one message for one locale does not mean forking the package. The version compatibility table in the README is a separate axis worth reading before you upgrade: package version 1.5 covers Laravel 6 through 9, 1.6 covers 9 and 10, 1.7 covers 9 and 10, 1.8 covers 9 through 11, 1.9 covers 9 through 12, and 2.0 covers 9 through 13.

Where laravel-validate is the wrong tool

The scope is narrow, which is a strength and a limit. If a rule already exists in Laravel, this package adds a dependency for nothing, and the framework's own rules for email, URL, IP and numeric ranges are already localised through Laravel's own translation files. The second limit is the dependency surface. The package is small in code, but it moves your validation layer from the framework to a third party, and that means your rules are now only as current as the package, and the compatibility table shows a different Laravel support window for each package line, so an upgrade of one is not independent of the other. The third is that the rules are format checks, not semantic checks. A ValidPhoneNumber rule can tell you a string is shaped like a phone number, and it cannot tell you the number exists or is assigned. The alternative worth naming is writing the rules yourself as custom Rule classes in your own application, which is not much code for one or two formats, keeps the message strings in your own lang files, and removes the version coupling entirely, at the cost of not having the rest of the catalogue. That is the trade: the package is worth it when you need many regional formats, and unnecessary when you need one.

Maintenance and the shape of the repository

The package is MIT licensed and published on Packagist as milwad/laravel-validate, with the homepage pointing there. The release history shows three tags in quick succession in 2026, v2.0.0 on 2026-04-15, v2.1.0 on 2026-05-07 and v2.2.0 on 2026-06-25, and the last push to the repository was on 2026-09-06, so the 2.x line is being worked on. The default branch is 1.x while the current releases are 2.x, which is a naming choice worth checking before you pin a version, since the documentation links in the README for the individual rules point at the 1.x tree. The repository carries a CHANGELOG, a composer.json, an .editorconfig, a phpunit.xml.dist with a .bak copy alongside it, and a docs/ directory with a markdown file per rule. The CI badges show a test workflow, an imports check, a Scrutinizer quality score and a DeepWiki link, so the project has a reasonable amount of automation around it for a package of this size.

Editorial conclusion

Adopt laravel-validate if your Laravel forms validate identifiers that the framework has no rule for, particularly Iranian and other regional formats, and you want the messages localised rather than hand written. Do not adopt it for rules Laravel already ships, since you would be adding a dependency for something the framework does. Verify first that the rule you need exists in the catalogue and that its message file exists for your locale, and decide early whether to use the plain string form of the rules or the service container form.

Frequently asked questions

How do I install laravel-validate in a Laravel project?

Run composer require milwad/laravel-validate. The package requires PHP 8.0 or newer and Laravel 9.0 or newer, and you can optionally publish the config file with the laravel-validate-config tag and language files with a validate-lang tag.

What is the using_container option for?

It decides how rules are resolved. With it set to true, a rule is written as a string such as required|ValidPhone and resolved through the service container. The shipped config sets it to false, in which case you instantiate the rule class yourself, for example ['required', new ValidPhoneNumber()].

How do I add a new language to laravel-validate?

The README says the package supports most languages, and if a language is not supported you can open a pull request for a new one or write your own. Messages live in the lang directory and are published per locale with the validate-lang tag.

Which validation rules does laravel-validate provide?

The README table lists rules including ValidBase64, ValidBitcoinAddress, ValidCamelCase, ValidCapitalCharWithNumber, ValidCarNumber and ValidCartNumberIran, with a documentation page per rule under docs. Each rule has its own markdown file with usage details.

Official sources

  1. License: MIT
  2. milwad-dev/laravel-validate on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/milwad-dev-laravel-validate.svg)](https://hysenlabs.com/projects/milwad-dev-laravel-validate)

Was this useful?