phil / phone
Phone numbers for PHP: parsed from what people type, validated and typed by country, formatted in E.164, international, national and tel: forms, on libphonenumber's metadata imported as PHP data
Requires
- php: >=8.5
- ext-ctype: *
- ext-dom: *
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^13.4
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-11 06:16:35 UTC
README
Phone numbers read as people type them, checked against their country's plan, and formatted.
phil/phone reads a number into a PhoneNumber, with or without its country code, spaced, dotted or with an
extension. It checks the number against its country's numbering plan and tells its type: mobile, landline,
toll-free and others. It writes the number in E.164, international, national and RFC 3966 tel: forms. It does
not guess a carrier, a time zone or a place, read numbers out of free text, or format as people type.
It is for PHP applications that store contact numbers and must show and dial them correctly across countries. The
numbering plans are libphonenumber's, 254 territories imported as PHP data by the library's own MetadataImporter;
the parsing and formatting are the library's own code. The library depends on no other package, only on ext-ctype,
ext-dom and ext-mbstring, and its plans follow libphonenumber's releases by running the importer again. The
imported data stays under the Apache License 2.0, so the package is under MIT and Apache-2.0.
In a Symfony application, reach for phil/phone-bundle: a form field, a validation constraint, a Doctrine column type
and Twig filters. phil/instant-messenger uses phil/phone to read the phone numbers that identify WhatsApp, Signal
or Viber handles. The design is a value type over plain data: a PhoneNumber keeps a country code, a national number
and an extension, and the library reads only the parts of the plans it uses.
Status
| Part | State |
|---|---|
PhoneNumber::parse(): country codes, international and national prefixes, extensions, tel: |
Implemented and tested |
region(), type(), isValid() against the numbering plans |
Implemented and tested |
format(): E.164, international, national, RFC 3966 |
Implemented and tested |
MetadataImporter: libphonenumber's XML to PHP data, 254 territories |
Implemented and tested |
Documentation
| Document | What it covers |
|---|---|
| Installation | Requirements and installing. |
| Parsing | What parse() reads, regions, extensions, refusals. |
| Validation and types | isValid(), region(), type(), and what each type means. |
| Formatting | The four formats, extensions, and storing a number. |
| Metadata | Where the numbering plans come from, their licence, and updating them. |
| Extension points | The ports, arguments and data an application chooses or replaces. |
| Testing | The library's tests and mutation bar. |
| Reference | Every type of the library, with its role. |
Quick start
composer require phil/phone
use Phil\Phone\PhoneFormat; use Phil\Phone\PhoneNumber; $number = PhoneNumber::parse('06 12 34 56 78', 'FR'); $number->isValid(); // true $number->type(); // PhoneNumberType::Mobile $number->format(PhoneFormat::International); // "+33 6 12 34 56 78" (string) $number; // "+33612345678"
Requirements
PHP 8.5 or later with ext-ctype, ext-dom and ext-mbstring. parse() measures text with ext-mbstring;
ext-dom and ext-ctype serve only the importer, but Composer requires them with the library.
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
The code is MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Parler Haut Interagir Librement project.
See LICENSE. The numbering plans in data/ come from libphonenumber, under the Apache License 2.0: see
NOTICE and data/LICENSE.