# How to Use the ValidPhoneNumber Rule in Laravel: Complete Guide

> Master the ValidPhoneNumber rule in Laravel. This guide teaches you to validate international and country-specific phone numbers efficiently. Improve your form validation today.

- Repository: [Milwad Khosravi/laravel-validate](https://github.com/milwad-dev/laravel-validate)
- Tags: how-to-guide
- Published: 2026-03-07

---

**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`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Rules/ValidPhoneNumber.php), the `passes()` method applies a generic regex when no country code is supplied.

```php
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'`.

```php
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 in [`src/Rules/ValidPhoneNumber.php`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Rules/ValidPhoneNumber.php), this class implements `Illuminate\Contracts\Validation\Rule`. It acts as the entry point, deciding whether to use generic or country‑specific logic.
- **`CountryPhoneCallback`** – Found in [`src/Utils/CountryPhoneCallback.php`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Utils/CountryPhoneCallback.php), this registry maintains the mapping between country codes and their validator classes.
- **`CountryPhoneValidator` interface** – Defined in [`src/Utils/CountryPhoneValidator/CountryPhoneValidator.php`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Utils/CountryPhoneValidator/CountryPhoneValidator.php), it enforces a `validate($value): bool` contract for all country validators.
- **Country‑specific validators** – Concrete implementations like `IRPhoneValidator` in [`src/Utils/CountryPhoneValidator/IRPhoneValidator.php`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Utils/CountryPhoneValidator/IRPhoneValidator.php) contain the regex patterns for individual nations.
- **`LaravelValidateServiceProvider`** – During its `boot()` method, this provider reads the `phone-country` mapping from [`config/laravel-validate.php`](https://github.com/milwad-dev/laravel-validate/blob/main/config/laravel-validate.php) and registers each validator with the `CountryPhoneCallback`.

### The Validation Process

When validation is triggered, the following sequence executes inside [`src/Rules/ValidPhoneNumber.php`](https://github.com/milwad-dev/laravel-validate/blob/main/src/Rules/ValidPhoneNumber.php):

1. If a country code is provided, the rule calls `CountryPhoneCallback::callPhoneValidator($code, $value)`.
2. The callback instantiates the appropriate validator class that was registered by the service provider.
3. The country validator runs its `validate()` method against the phone number.
4. If no country code is supplied, the rule applies the generic regex directly.
5. If an unsupported country code is passed, a `BadMethodCallException` is thrown, as covered in [`tests/Rules/ValidPhoneNumberTest.php`](https://github.com/milwad-dev/laravel-validate/blob/main/tests/Rules/ValidPhoneNumberTest.php) under `test_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`](https://github.com/milwad-dev/laravel-validate/blob/main/config/laravel-validate.php). The `LaravelValidateServiceProvider` then registers the `valid_phone_number` alias.

```php
// 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:

```php
// 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:

```php
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::IRAN` or `'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 by `LaravelValidateServiceProvider`.
- Enable **string syntax** (`valid_phone_number:IR`) by setting `using_container` to `true` in [`config/laravel-validate.php`](https://github.com/milwad-dev/laravel-validate/blob/main/config/laravel-validate.php).
- Country mappings are configured in the `phone-country` array, 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`](https://github.com/milwad-dev/laravel-validate/blob/main/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`](https://github.com/milwad-dev/laravel-validate/blob/main/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()`.