giggsey/libphonenumber-for-php-lite
Lite PHP port of Google’s libphonenumber: parse, validate, format, and store international phone numbers. Includes core PhoneNumberUtils only (no geolocation/carrier/short number info). Requires PHP 8.1+ and mbstring; install via Composer.
Installation:
composer require giggsey/libphonenumber-for-php-lite
Ensure your composer.json includes "require": {"php": "^8.1"} and the mbstring extension is enabled.
First Use Case: Parse and validate a phone number in a Laravel controller or service:
use libphonenumber\PhoneNumberUtil;
$phoneUtil = PhoneNumberUtil::getInstance();
$number = $phoneUtil->parse('+14155552671', 'US');
$isValid = $phoneUtil->isValidNumber($number);
Where to Look First:
public function validatePhoneNumber(string $phone, string $regionCode): bool
{
$phoneUtil = PhoneNumberUtil::getInstance();
try {
$number = $phoneUtil->parse($phone, $regionCode);
return $phoneUtil->isValidNumber($number);
} catch (NumberParseException $e) {
return false;
}
}
FormRequest validator or a custom validation rule.+1 (415) 555-2671).public function formatPhoneNumber(PhoneNumberInterface $number, string $format = PhoneNumberFormat::NATIONAL): string
{
$phoneUtil = PhoneNumberUtil::getInstance();
return $phoneUtil->format($number, $format);
}
{{ formatPhoneNumber($user->phoneNumber) }}
public function normalizePhoneNumber(string $phone, string $regionCode): string
{
$phoneUtil = PhoneNumberUtil::getInstance();
$number = $phoneUtil->parse($phone, $regionCode);
return $phoneUtil->format($number, PhoneNumberFormat::E164);
}
$table->string('phone_number')->comment('Stored in E.164 format');
public function getNumberType(PhoneNumberInterface $number): string
{
$phoneUtil = PhoneNumberUtil::getInstance();
return $phoneUtil->getNumberType($number);
}
if ($phoneUtil->getNumberType($number) === PhoneNumberType::MOBILE) {
// Apply mobile-specific logic
}
public function formatForInternationalDialing(PhoneNumberInterface $number, string $callingCountryCode): string
{
$phoneUtil = PhoneNumberUtil::getInstance();
return $phoneUtil->formatOutOfCountryCallingNumber($number, $callingCountryCode);
}
Register the PhoneNumberUtil instance as a singleton in AppServiceProvider:
public function register()
{
$this->app->singleton(PhoneNumberUtil::class, function () {
return PhoneNumberUtil::getInstance();
});
}
Create a reusable validation rule:
namespace App\Rules;
use libphonenumber\PhoneNumberUtil;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\NumberParseException;
class ValidPhoneNumber implements Rule
{
protected $regionCode;
public function __construct(string $regionCode)
{
$this->regionCode = $regionCode;
}
public function passes($attribute, $value)
{
$phoneUtil = PhoneNumberUtil::getInstance();
try {
$number = $phoneUtil->parse($value, $this->regionCode);
return $phoneUtil->isValidNumber($number);
} catch (NumberParseException) {
return false;
}
}
public function message()
{
return 'The :attribute is invalid.';
}
}
Usage:
'phone' => ['required', new ValidPhoneNumber('US')],
Add phone number formatting to Eloquent models:
public function getPhoneNumberAttribute($value)
{
if (empty($value)) return $value;
$phoneUtil = app(PhoneNumberUtil::class);
$number = $phoneUtil->parse($value, 'US');
return $phoneUtil->format($number, PhoneNumberFormat::NATIONAL);
}
public function setPhoneNumberAttribute($value)
{
$phoneUtil = app(PhoneNumberUtil::class);
$this->attributes['phone_number'] = $phoneUtil->format(
$phoneUtil->parse($value, 'US'),
PhoneNumberFormat::E164
);
}
Region Code Ambiguity:
parse("123")) may fail or return unexpected results.parse("123", "US")).parse("123", null) and handle NumberParseException to infer the region.Invalid Metadata:
composer update giggsey/libphonenumber-for-php-lite
Performance with Large Datasets:
PhoneNumberUtil instance (already handled by the singleton pattern) and avoid redundant parsing.Edge Cases in Validation:
getNumberType() to filter out unwanted types:
$type = $phoneUtil->getNumberType($number);
if ($type === PhoneNumberType::VOICEMAIL) {
return false;
}
Time Zone Dependencies:
Logging Parsing Errors:
try {
$number = $phoneUtil->parse($phone, $region);
} catch (NumberParseException $e) {
Log::warning("Invalid phone number: {$phone} (Region: {$region})", ['error' => $e->getMessage()]);
}
Testing with Examples:
getExampleNumber() to test edge cases:
$example = $phoneUtil->getExampleNumber('US');
$exampleMobile = $phoneUtil->getExampleNumberByType('US', PhoneNumberType::MOBILE);
Comparing Numbers:
isNumberMatch() to check if two numbers might refer to the same entity:
$match = $phoneUtil->isNumberMatch($number1, $number2);
if ($match === PhoneNumberMatch::POSSIBLE) {
// Numbers might be the same
}
Custom Formatting Patterns:
class CustomPhoneNumberUtil extends PhoneNumberUtil
{
protected function chooseFormattingPatternForNumber($regionCode, $number)
{
if ($regionCode === 'US') {
return '!N<1>XXXXXXX!'; // Custom pattern
}
return parent::chooseFormattingPatternForNumber($regionCode, $number);
}
}
Database Storage:
How can I help you explore Laravel packages today?