Formatting Phone Numbers
Formatting phone numbers correctly is essential for user experience and international communication. This guide covers all formatting options available in libphonenumber for PHP.
There are four main format types, each serving a specific purpose:
E164
International
National
RFC3966
E164 is the international standard for phone numbers, used for storage and APIs:$phoneUtil = PhoneNumberUtil :: getInstance ();
$number = $phoneUtil -> parse ( '044 668 18 00' , 'CH' );
echo $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: E164
);
// Output: +41446681800
Use for : Database storage, API payloads, SMS gatewaysINTERNATIONAL is human-readable with country code, used for international display:echo $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: INTERNATIONAL
);
// Output: +41 44 668 18 00
Use for : Displaying to international users, contact listsNATIONAL is the domestic format without country code:echo $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: NATIONAL
);
// Output: 044 668 18 00
Use for : Displaying to users in the same countryRFC3966 is the URI format for tel: links:echo $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: RFC3966
);
// Output: tel:+41-44-668-18-00
Use for : HTML tel: links, mobile click-to-call
Get PhoneNumberUtil Instance
$phoneUtil = \libphonenumber\ PhoneNumberUtil :: getInstance ();
Parse the Number
$number = $phoneUtil -> parse ( '+41446681800' , null );
Format as Needed
// For display to international users
$international = $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: INTERNATIONAL
);
// For database storage
$e164 = $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: E164
);
// For HTML links
$tel = $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: RFC3966
);
Context-Aware Formatting
Format a number as it would be dialed from another country:
$phoneUtil = PhoneNumberUtil :: getInstance ();
$gbNumber = $phoneUtil -> parse ( '0117 496 0123' , 'GB' );
// How to dial from France (IDD: 00)
echo $phoneUtil -> formatOutOfCountryCallingNumber ( $gbNumber , 'FR' );
// Output: 00 44 117 496 0123
// How to dial from US (IDD: 011)
echo $phoneUtil -> formatOutOfCountryCallingNumber ( $gbNumber , 'US' );
// Output: 011 44 117 496 0123
// From same country (GB)
echo $phoneUtil -> formatOutOfCountryCallingNumber ( $gbNumber , 'GB' );
// Output: 0117 496 0123
Use this when showing phone numbers to users in different countries, automatically displaying the correct dialing format.
Format a number for mobile device dialing:
$phoneUtil = PhoneNumberUtil :: getInstance ();
$auNumber = $phoneUtil -> parse ( '1300 123 456' , 'AU' );
// Format for dialing in Australia (with formatting)
echo $phoneUtil -> formatNumberForMobileDialing ( $auNumber , 'AU' , true );
// Output: 1300 123 456
// Format for dialing in Australia (without formatting)
echo $phoneUtil -> formatNumberForMobileDialing ( $auNumber , 'AU' , false );
// Output: 1300123456
// Can't be dialed from US (returns empty string)
echo $phoneUtil -> formatNumberForMobileDialing ( $auNumber , 'US' , true );
// Output: ""
If a number cannot be dialed from the specified region, this method returns an empty string.
Some countries (like Argentina) use carrier codes for domestic dialing:
$phoneUtil = PhoneNumberUtil :: getInstance ();
$arNumber = $phoneUtil -> parse ( '92234654321' , 'AR' );
// Format with carrier code 14
echo $phoneUtil -> formatNationalNumberWithCarrierCode ( $arNumber , '14' );
// Output: 02234 14 65-4321
// Format without carrier code
echo $phoneUtil -> formatNationalNumberWithCarrierCode ( $arNumber , '' );
// Output: 02234 65-4321
$phoneUtil = PhoneNumberUtil :: getInstance ();
// Create number with preferred carrier
$arNumber = new \libphonenumber\ PhoneNumber ();
$arNumber -> setCountryCode ( 54 );
$arNumber -> setNationalNumber ( 91234125678 );
$arNumber -> setPreferredDomesticCarrierCode ( '19' );
// Uses preferred carrier (19) over fallback (15)
echo $phoneUtil -> formatNationalNumberWithPreferredCarrierCode ( $arNumber , '15' );
// Output: 01234 19 12-5678
Extensions are automatically included in formatted output:
$phoneUtil = PhoneNumberUtil :: getInstance ();
$number = $phoneUtil -> parse ( '0117 496 0123 ext. 456' , 'GB' );
echo $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: INTERNATIONAL
);
// Output: +44 117 496 0123 ext. 456
echo $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: E164
);
// Output: +441174960123 (E164 doesn't include extensions)
E164 format never includes extensions as it’s meant for routing purposes only.
Web Display
HTML Click-to-Call
Database Storage
function formatForWebDisplay (
string $phoneNumber ,
string $userRegion ,
string $numberRegion
) : string {
$phoneUtil = PhoneNumberUtil :: getInstance ();
try {
$number = $phoneUtil -> parse ( $phoneNumber , $numberRegion );
if ( ! $phoneUtil -> isValidNumber ( $number )) {
return $phoneNumber ; // Return as-is if invalid
}
// Same country: national format
if ( $userRegion === $numberRegion ) {
return $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: NATIONAL
);
}
// Different country: international format
return $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: INTERNATIONAL
);
} catch ( \libphonenumber\ NumberParseException $e ) {
return $phoneNumber ;
}
}
// Usage
echo formatForWebDisplay ( '+441174960123' , 'GB' , 'GB' );
// Output: 0117 496 0123
echo formatForWebDisplay ( '+441174960123' , 'US' , 'GB' );
// Output: +44 117 496 0123
function createClickToCallLink (
string $phoneNumber ,
string $region
) : string {
$phoneUtil = PhoneNumberUtil :: getInstance ();
try {
$number = $phoneUtil -> parse ( $phoneNumber , $region );
// Get RFC3966 format for href
$href = $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: RFC3966
);
// Get international format for display
$display = $phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: INTERNATIONAL
);
return sprintf (
'<a href="%s">%s</a>' ,
htmlspecialchars ( $href ),
htmlspecialchars ( $display )
);
} catch ( \libphonenumber\ NumberParseException $e ) {
return htmlspecialchars ( $phoneNumber );
}
}
// Usage
echo createClickToCallLink ( '+441174960123' , null );
// Output: <a href="tel:+44-117-496-0123">+44 117 496 0123</a>
class PhoneNumberFormatter
{
private PhoneNumberUtil $phoneUtil ;
public function __construct ()
{
$this -> phoneUtil = PhoneNumberUtil :: getInstance ();
}
// Store in E164 format
public function formatForStorage (
string $input ,
string $region
) : ? string {
try {
$number = $this -> phoneUtil -> parse ( $input , $region );
if ( ! $this -> phoneUtil -> isValidNumber ( $number )) {
return null ;
}
// Always store as E164
return $this -> phoneUtil -> format (
$number ,
\libphonenumber\ PhoneNumberFormat :: E164
);
} catch ( \libphonenumber\ NumberParseException $e ) {
return null ;
}
}
// Retrieve and format for display
public function formatForDisplay (
string $e164Number ,
string $userRegion
) : string {
try {
$number = $this -> phoneUtil -> parse ( $e164Number , null );
return $this -> phoneUtil -> formatOutOfCountryCallingNumber (
$number ,
$userRegion
);
} catch ( \libphonenumber\ NumberParseException $e ) {
return $e164Number ;
}
}
}
// Usage
$formatter = new PhoneNumberFormatter ();
// Store
$stored = $formatter -> formatForStorage ( '0117 496 0123' , 'GB' );
// Result: "+441174960123"
// Display
$display = $formatter -> formatForDisplay ( $stored , 'GB' );
// Result: "0117 496 0123"
Here’s how different countries format in each style:
Switzerland
United States
United Kingdom
$phoneUtil = PhoneNumberUtil :: getInstance ();
$number = $phoneUtil -> parse ( '044 668 18 00' , 'CH' );
echo $phoneUtil -> format ( $number , PhoneNumberFormat :: E164 );
// +41446681800
echo $phoneUtil -> format ( $number , PhoneNumberFormat :: INTERNATIONAL );
// +41 44 668 18 00
echo $phoneUtil -> format ( $number , PhoneNumberFormat :: NATIONAL );
// 044 668 18 00
echo $phoneUtil -> format ( $number , PhoneNumberFormat :: RFC3966 );
// tel:+41-44-668-18-00
Best Practices
Store in E164 Always store phone numbers in E164 format for consistency and easy querying
Display with Context Use formatOutOfCountryCallingNumber() to show the right format for the user’s location
Use RFC3966 for Links Always use RFC3966 format for tel: links to ensure compatibility
Validate Before Formatting Always validate numbers before formatting to ensure quality
Next Steps
Number Formats Reference Complete documentation of all format constants
As-You-Type Formatting Real-time formatting as users type
PhoneNumberUtil API Full API reference for formatting methods
Core Concepts Understanding different number formats