PHPackages                             wal3fo/phone-country - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. wal3fo/phone-country

ActiveLibrary

wal3fo/phone-country
====================

Resolve country code from phone number for Laravel.

v1.0.2(1mo ago)02MITPHPPHP ^8.0

Since Mar 19Pushed 1mo agoCompare

[ Source](https://github.com/wal3fo/Phone-Country-Resolver)[ Packagist](https://packagist.org/packages/wal3fo/phone-country)[ RSS](/packages/wal3fo-phone-country/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (1)Versions (4)Used By (0)

phone-country-resolver
======================

[](#phone-country-resolver)

[![Latest Version on Packagist](https://camo.githubusercontent.com/61b3889ef30a394b339ad19d050579021c6b465ebd7689f67b09a3fd74994e07/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f77616c33666f2f70686f6e652d636f756e7472792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wal3fo/phone-country)[![Total Downloads](https://camo.githubusercontent.com/fac0d3085862daf0b9a39671c0c1b6901dfb5c49f4ea02217cddede5c84c45e1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f77616c33666f2f70686f6e652d636f756e7472792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wal3fo/phone-country)[![License](https://camo.githubusercontent.com/adf702a45369437a43b94ccf8423d3fafefa0067fc6aa0120216a48df99d1849/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f77616c33666f2f70686f6e652d636f756e7472792e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/wal3fo/phone-country)

A lightweight Laravel package to resolve **ISO 3166-1 alpha-2 country codes** from phone numbers. Supports international prefixes, double-zero formats, numeric-only inputs, and local number fallbacks — with zero configuration required.

---

What's New in v1.0.1
--------------------

[](#whats-new-in-v101)

- **`PhoneResult` object** — `resolve()` now returns a rich result with country name, dial code, E.164 format, and more
- **Laravel validation rule** — `PhoneCountryRule` integrates directly with Laravel's validator
- **Batch resolution** — `resolveMany()` resolves an array of numbers in one call
- **E.164 normalization** — `normalize()` returns a standardized phone string for database storage
- **Publishable config** — set a global default country once via `config/phone-country.php`
- `resolveCountryCode()` is kept as a fully backward-compatible alias — nothing breaks

---

Features
--------

[](#features)

- Resolves country codes from international prefixes (e.g. `+1`, `0044`, `212`)
- Returns a rich `PhoneResult` object with name, dial code, format, and E.164
- Built-in Laravel validation rule with country allowlist and strict mode
- Handles local phone formats starting with `0` via a configurable fallback
- Longest-prefix matching for accurate resolution of overlapping codes (e.g. NANP)
- Registered as a singleton — supports both static calls and dependency injection
- Auto-discovered by Laravel — no manual provider registration needed

---

Installation
------------

[](#installation)

```
composer require wal3fo/phone-country
```

Optionally publish the config file to set a global default country:

```
php artisan vendor:publish --tag=phone-country-config
```

---

Usage
-----

[](#usage)

### resolve() — recommended

[](#resolve--recommended)

`resolve()` returns a `PhoneResult` object with everything you need:

```
use Wal3fo\PhoneCountry\PhoneCountryService;

$result = PhoneCountryService::resolve('+212612345678');

$result->countryCode;  // 'MA'
$result->countryName;  // 'Morocco'
$result->dialCode;     // '+212'
$result->isResolved;   // true
$result->format;       // 'international'
$result->e164;         // '+212612345678'
$result->isValid();    // true
$result->toArray();    // ready for API responses

// Still works as a string
echo $result;          // 'MA'
```

With a local number fallback:

```
$result = PhoneCountryService::resolve('0612345678', 'MA');
$result->countryCode;  // 'MA'
$result->format;       // 'local'
$result->e164;         // '+212612345678'
```

### resolveMany() — batch resolution

[](#resolvemany--batch-resolution)

```
$results = PhoneCountryService::resolveMany([
    '+212612345678',
    '+33612345678',
    '0612345678',
], 'MA');

// Returns PhoneResult[] in the same order
```

### normalize() — E.164 for database storage

[](#normalize--e164-for-database-storage)

```
PhoneCountryService::normalize('+212612345678');      // '+212612345678'
PhoneCountryService::normalize('00212612345678');     // '+212612345678'
PhoneCountryService::normalize('0612345678', 'MA');   // '+212612345678'
PhoneCountryService::normalize('0612345678');         // null (unresolvable)
```

### Validation Rule

[](#validation-rule)

Use `PhoneCountryRule` directly inside your Laravel form requests or controllers:

```
use Wal3fo\PhoneCountry\Rules\PhoneCountryRule;

// Accept any valid international number
'phone' => ['required', new PhoneCountryRule()]

// Accept international or local numbers, with Morocco as fallback
'phone' => ['required', new PhoneCountryRule('MA')]

// Restrict to specific countries
'phone' => ['required', new PhoneCountryRule(['MA', 'FR', 'ES'])]

// Strict mode: reject local 0xxx formats, require full international format
'phone' => ['required', new PhoneCountryRule('MA', strict: true)]
```

Example in a Form Request:

```
use Wal3fo\PhoneCountry\Rules\PhoneCountryRule;

class RegisterRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name'  => ['required', 'string'],
            'phone' => ['required', 'string', new PhoneCountryRule('MA')],
        ];
    }
}
```

### Dependency Injection

[](#dependency-injection)

The service is registered as a singleton and can be injected directly:

```
use Wal3fo\PhoneCountry\PhoneCountryService;

class UserProfileController extends Controller
{
    public function __construct(
        protected PhoneCountryService $phoneService
    ) {}

    public function update(Request $request)
    {
        $result = $this->phoneService->resolve($request->phone_number);

        $user->update([
            'phone'        => $result->e164,
            'country_code' => $result->countryCode,
        ]);
    }
}
```

### resolveCountryCode() — backward compatible

[](#resolvecountrycode--backward-compatible)

The original method still works exactly as before:

```
PhoneCountryService::resolveCountryCode('+212612345678');       // 'MA'
PhoneCountryService::resolveCountryCode('0612345678', 'MA');   // 'MA'
PhoneCountryService::resolveCountryCode('0612345678');         // 'XX'
```

---

Examples
--------

[](#examples)

InputCountry CodeCountry NameFormat`+212612345678``MA`Moroccointernational`00212612345678``MA`Moroccointernational`212612345678``MA`Morocconumeric`0612345678` + `'MA'``MA`Moroccolocal`0612345678``XX`Unknownlocal`+1 242 123 4567``BS`Bahamasinternational`+33612345678``FR`Franceinternational---

Configuration
-------------

[](#configuration)

Publish the config file to set global defaults:

```
php artisan vendor:publish --tag=phone-country-config
```

```
// config/phone-country.php
return [
    'default_country' => env('PHONE_COUNTRY_DEFAULT', 'XX'),
    'unknown_code'    => 'XX',
];
```

Or set it in your `.env`:

```
PHONE_COUNTRY_DEFAULT=MA
```

---

Notes
-----

[](#notes)

**Auto-discovery** — The `PhoneCountryServiceProvider` is automatically registered via Laravel's package discovery. No manual setup is required.

**Performance** — Prefix lookup is optimized using longest-prefix matching. For high-volume workloads, consider caching resolved results:

```
$result = Cache::remember("phone_country:{$phone}", 3600, fn () =>
    PhoneCountryService::resolve($phone)
);
```

**Data accuracy** — The prefix map covers most countries globally. Longer, more specific prefixes (such as North American area codes) take priority over shorter ones to ensure correct resolution.

---

Contributing
------------

[](#contributing)

Contributions are welcome. To get started:

1. Fork the repository.
2. Create a feature branch: `git checkout -b feature/your-feature`
3. Commit your changes: `git commit -m 'Add your feature'`
4. Push to the branch: `git push origin feature/your-feature`
5. Open a Pull Request.

Please ensure your changes are well-tested and consistent with the existing code style.

---

Changelog
---------

[](#changelog)

### v1.0.2

[](#v102)

- Added `PhoneResult` value object returned by `resolve()`
- Added `resolveMany()` for batch resolution
- Added `normalize()` for E.164 output
- Added `PhoneCountryRule` Laravel validation rule with allowlist and strict mode
- Added publishable config with `default_country` support
- `resolveCountryCode()` kept as backward-compatible alias

### v1.0.1

[](#v101)

- Initial release with `resolveCountryCode()` and longest-prefix matching

---

License
-------

[](#license)

The MIT License (MIT). See [LICENSE](LICENSE) for full details.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

53d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d2ce4983cf5acecde9209ea787f0a01c51fc9c653e25eb251e79dd6348299f67?d=identicon)[wal3fo](/maintainers/wal3fo)

---

Top Contributors

[![wal3fo](https://avatars.githubusercontent.com/u/92164512?v=4)](https://github.com/wal3fo "wal3fo (12 commits)")

### Embed Badge

![Health badge](/badges/wal3fo-phone-country/health.svg)

```
[![Health](https://phpackages.com/badges/wal3fo-phone-country/health.svg)](https://phpackages.com/packages/wal3fo-phone-country)
```

###  Alternatives

[fumeapp/modeltyper

Generate TypeScript interfaces from Laravel Models

196277.9k](/packages/fumeapp-modeltyper)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
