Skip to main content

The PhoneNumber Object

The PhoneNumber class is the core data structure in libphonenumber for PHP. It represents a parsed phone number with all its components and metadata.
Do not create PhoneNumber objects directly. Always use PhoneNumberUtil::parse() to parse a number and return a PhoneNumber object.

Object Structure

A PhoneNumber object contains the following key properties:
PropertyTypeDescription
countryCodeintThe country calling code (e.g., 1 for US/Canada, 44 for UK)
nationalNumberstringThe national significant number without formatting
extensionstringOptional phone extension (up to 40 digits)
italianLeadingZeroboolWhether the number has a leading zero (for certain countries)
numberOfLeadingZerosintCount of leading zeros (default: 1)
rawInputstringThe original input string before canonicalization
countryCodeSourceCountryCodeSourceHow the country code was derived
preferredDomesticCarrierCodestringCarrier selection code for domestic calls

Example PhoneNumber Object

When you parse a UK phone number:
$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
$number = $phoneUtil->parse('0117 496 0123', 'GB');
The resulting object contains:
object(libphonenumber\PhoneNumber) {
  ["countryCode":protected] => int(44)
  ["nationalNumber":protected] => string(10) "1174960123"
  ["extension":protected] => NULL
  ["italianLeadingZero":protected] => NULL
  ["numberOfLeadingZeros":protected] => int(1)
  // ... other properties
}

Accessing Phone Number Properties

The PhoneNumber class provides getter methods for all properties:
$countryCode = $number->getCountryCode(); // 44
$nationalNumber = $number->getNationalNumber(); // "1174960123"
$extension = $number->getExtension(); // null or extension string

Phone Number Extensions

Phone extensions are stored as strings to accommodate leading zeros:
$number = $phoneUtil->parse('+1-650-253-0000 ext. 123', 'US');
if ($number->hasExtension()) {
    echo $number->getExtension(); // "123"
}
Extensions can be up to 40 digits long, though most are much shorter in practice.

Italian Leading Zeros

Some countries (notably Italy) have numbers where leading zeros are significant when dialing internationally:
$italianNumber = $phoneUtil->parse('+39 02 1234567', null);
if ($italianNumber->isItalianLeadingZero()) {
    echo "This number has a leading zero";
    echo $italianNumber->getNumberOfLeadingZeros(); // 1
}

Phone Number Types

The library categorizes phone numbers into different types defined by the PhoneNumberType enum:

Available Types

TypeValueDescription
FIXED_LINE0Traditional landline numbers
MOBILE1Mobile/cellular numbers
FIXED_LINE_OR_MOBILE2Cannot distinguish between fixed-line and mobile
TOLL_FREE3Freephone lines (e.g., 1-800 numbers)

Determining Number Type

Use getNumberType() to identify a phone number’s type:
$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
$number = $phoneUtil->parse('07400 123456', 'GB');

$type = $phoneUtil->getNumberType($number);

if ($type === \libphonenumber\PhoneNumberType::MOBILE) {
    echo "This is a mobile number";
} elseif ($type === \libphonenumber\PhoneNumberType::FIXED_LINE) {
    echo "This is a landline";
}

FIXED_LINE_OR_MOBILE Type

In some regions (notably the USA and Canada), it’s impossible to distinguish between fixed-line and mobile numbers by examining the number itself:
$usNumber = $phoneUtil->parse('(650) 253-0000', 'US');
$type = $phoneUtil->getNumberType($usNumber);

// Returns PhoneNumberType::FIXED_LINE_OR_MOBILE
The FIXED_LINE_OR_MOBILE type is never returned by getSupportedTypesForRegion() as it’s a convenience type representing ambiguity.

Checking Supported Types by Region

Find out which phone number types are available in a specific region:
$types = $phoneUtil->getSupportedTypesForRegion('GB');
// Returns array containing FIXED_LINE, MOBILE, TOLL_FREE, etc.

foreach ($types as $type) {
    echo $type->name . "\n";
}

Geographical vs Non-Geographical Numbers

Some phone numbers have a geographical association:
$number = $phoneUtil->parse('+44 117 496 0123', null);

if ($phoneUtil->isNumberGeographical($number)) {
    echo "This number is associated with a geographical region";
}
  • FIXED_LINE - Always geographical
  • MOBILE - Geographical in some countries (e.g., Argentina, Brazil, China, Mexico)
  • FIXED_LINE_OR_MOBILE - Considered possibly geographical
  • All other types are non-geographical

Working with Different Types

Getting Example Numbers

Retrieve example numbers for testing:
// Get any example number for a region
$exampleNumber = $phoneUtil->getExampleNumber('GB');

// Get an example of a specific type
$mobileExample = $phoneUtil->getExampleNumberForType(
    'GB',
    \libphonenumber\PhoneNumberType::MOBILE
);

// Get an invalid example (useful for testing)
$invalidExample = $phoneUtil->getInvalidExampleNumber('GB');

Type-Specific Validation

Check if a number is possible for a specific type:
$result = $phoneUtil->isPossibleNumberForTypeWithReason(
    $number,
    \libphonenumber\PhoneNumberType::MOBILE
);

if ($result === \libphonenumber\ValidationResult::IS_POSSIBLE) {
    echo "Number could be a mobile number";
}

Best Practices

Never manually construct PhoneNumber objects. Always use PhoneNumberUtil::parse() to ensure proper validation and parsing.
The phone number type is determined by pattern matching against metadata. It does not verify if the number is currently in use or assigned to a specific carrier.

Comparing Phone Numbers

Use the equals() method to compare two PhoneNumber objects:
$number1 = $phoneUtil->parse('+44 117 496 0123', null);
$number2 = $phoneUtil->parse('0117 496 0123', 'GB');

if ($number1->equals($number2)) {
    echo "These numbers are identical";
}

String Representation

Convert a PhoneNumber to a readable string for debugging:
echo $number->__toString();
// Output: Country Code: 44 National Number: 1174960123

Build docs developers (and LLMs) love