How to Use the ValidPhoneNumber Rule in Laravel: Complete Guide
The ValidPhoneNumber rule validates both generic international phone numbers and country‑specific formats by delegating to specialized validators or falling back to a flexible regex pattern.
The ValidPhoneNumber rule from the milwad-dev/laravel-validate package provides a robust, extensible solution for phone validation in Laravel applications. Whether you need to accept international numbers or enforce strict national formats, this rule adapts through a pluggable architecture driven by configuration.
Basic Usage Patterns
Generic Phone Validation (No Country)
To accept any well‑formed international number, instantiate the rule without arguments. According to the source code in src/Rules/ValidPhoneNumber.php, the passes() method applies a generic regex when no country code is supplied.
use Milwad\LaravelValidate\Rules\ValidPhoneNumber;
$request->validate([
'phone' => ['required', new ValidPhoneNumber],
]);
The fallback regex /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/ accommodates optional plus signs, parentheses, spaces, dots, and dashes.
Country‑Specific Validation
To enforce exact formats for a specific nation, pass a country code to the constructor. Use constants from Milwad\LaravelValidate\Utils\Country or raw strings like 'IR' or 'EN'.
use Milwad\LaravelValidate\Rules\ValidPhoneNumber;
use Milwad\LaravelValidate\Utils\Country;
// Using the Country constant
$request->validate([
'phone' => ['required', new ValidPhoneNumber(Country::IRAN)],
]);
// Using a raw country code
$request->validate([
'phone' => ['required', new ValidPhoneNumber('EN')],
]);
Architecture and Validation Flow
Core Components
The validation system relies on a delegation pattern with several key classes:
ValidPhoneNumber– Located insrc/Rules/ValidPhoneNumber.php, this class implementsIlluminate\Contracts\Validation\Rule. It acts as the entry point, deciding whether to use generic or country‑specific logic.CountryPhoneCallback– Found insrc/Utils/CountryPhoneCallback.php, this registry maintains the mapping between country codes and their validator classes.CountryPhoneValidatorinterface – Defined insrc/Utils/CountryPhoneValidator/CountryPhoneValidator.php, it enforces avalidate($value): boolcontract for all country validators.- Country‑specific validators – Concrete implementations like
IRPhoneValidatorinsrc/Utils/CountryPhoneValidator/IRPhoneValidator.phpcontain the regex patterns for individual nations. LaravelValidateServiceProvider– During itsboot()method, this provider reads thephone-countrymapping fromconfig/laravel-validate.phpand registers each validator with theCountryPhoneCallback.
The Validation Process
When validation is triggered, the following sequence executes inside src/Rules/ValidPhoneNumber.php:
- If a country code is provided, the rule calls
CountryPhoneCallback::callPhoneValidator($code, $value). - The callback instantiates the appropriate validator class that was registered by the service provider.
- The country validator runs its
validate()method against the phone number. - If no country code is supplied, the rule applies the generic regex directly.
- If an unsupported country code is passed, a
BadMethodCallExceptionis thrown, as covered intests/Rules/ValidPhoneNumberTest.phpundertest_if_phone_number_validate_method_is_not_exists.
Advanced Configuration
Enabling Container‑Based Shortcut Syntax
To use string‑based validation rules instead of object instantiation, enable the container integration. Set 'using_container' => true in config/laravel-validate.php. The LaravelValidateServiceProvider then registers the valid_phone_number alias.
// config/laravel-validate.php
'using_container' => true,
// Usage in validation
$request->validate([
'phone' => 'required|valid_phone_number:IR',
]);
Extending with Custom Countries
Add support for additional nations by creating a class implementing the CountryPhoneValidator interface and registering it in the configuration:
// config/laravel-validate.php
'phone-country' => [
'IR' => \Milwad\LaravelValidate\Utils\CountryPhoneValidator\IRPhoneValidator::class,
'EN' => \Milwad\LaravelValidate\Utils\CountryPhoneValidator\ENPhoneValidator::class,
'JP' => \App\Validators\JapanPhoneValidator::class, // Your custom implementation
],
Programmatic Validation Examples
Using the Validator Facade
For dynamic validation outside of form requests, use the Validator facade directly with the rule:
use Illuminate\Support\Facades\Validator;
use Milwad\LaravelValidate\Rules\ValidPhoneNumber;
use Milwad\LaravelValidate\Utils\Country;
$data = ['phone' => '+447975777666'];
$rules = ['phone' => ['required', new ValidPhoneNumber(Country::ENGLAND)]];
$passes = Validator::make($data, $rules)->passes(); // Returns true
Summary
- The ValidPhoneNumber rule supports both flexible generic validation and strict country‑specific format enforcement.
- Pass a country code (e.g.,
Country::IRANor'EN') to validate against national patterns, or omit it for international numbers. - The architecture delegates validation to specialized classes via
CountryPhoneCallback, which resolves validators registered byLaravelValidateServiceProvider. - Enable string syntax (
valid_phone_number:IR) by settingusing_containertotrueinconfig/laravel-validate.php. - Country mappings are configured in the
phone-countryarray, allowing easy extension with custom validators.
Frequently Asked Questions
Can I use ValidPhoneNumber without specifying a country?
Yes. When you instantiate new ValidPhoneNumber without arguments, the rule validates against a generic regex that accepts most international formats, including optional plus signs, parentheses, and various separators.
What happens if I pass an unsupported country code?
The system throws a BadMethodCallException. This behavior is explicitly tested in tests/Rules/ValidPhoneNumberTest.php. Always ensure the country code exists in the phone-country configuration mapping before using it.
How do I add support for a new country?
Create a class implementing the CountryPhoneValidator interface with a validate($value): bool method containing your regex logic. Register this class in config/laravel-validate.php under the phone-country array. The LaravelValidateServiceProvider automatically registers it during the boot phase.
Is there a performance difference between generic and country-specific validation?
Country-specific validation involves an additional lookup through CountryPhoneCallback and instantiation of a specific validator class, but the overhead is negligible for typical HTTP requests. Generic validation is marginally faster as it applies a single regex directly in ValidPhoneNumber::passes().
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →