Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Libphonenumber For Php Laravel Package

20steps/libphonenumber-for-php

PHP port/wrapper of Google’s libphonenumber, providing tools to parse, validate, and format international phone numbers, detect regions and number types, and handle country calling codes for consistent phone handling in your apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require giggsey/libphonenumber-for-php
    

    Add to composer.json if not auto-loaded:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "libphonenumber\\": "vendor/giggsey/libphonenumber-for-php/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case: Parse and format a phone number in a Laravel controller:

    use libphonenumber\PhoneNumberUtil;
    use libphonenumber\PhoneNumberFormat;
    
    $phoneUtil = PhoneNumberUtil::getInstance();
    $number = $phoneUtil->parse('+14155552671', 'US');
    $formatted = $phoneUtil->format($number, PhoneNumberFormat::E164);
    // Output: +14155552671
    
  3. Key Classes to Know:

    • PhoneNumberUtil: Core utility for parsing, formatting, and validating.
    • PhoneNumber: Represents a parsed phone number.
    • PhoneNumberFormat: Constants for formatting styles (E164, INTERNATIONAL, etc.).

Implementation Patterns

Common Workflows

1. Validation & Sanitization

// Validate and parse a user-submitted phone number
$phoneUtil = PhoneNumberUtil::getInstance();
try {
    $number = $phoneUtil->parse($request->input('phone'), $request->input('country_code'));
    if (!$phoneUtil->isValidNumber($number)) {
        throw new \InvalidArgumentException('Invalid phone number');
    }
} catch (\libphonenumber\NumberParseException $e) {
    return back()->withErrors(['phone' => 'Invalid format']);
}

2. Formatting for Display

// Format for user-friendly display (e.g., in a view)
$formatted = $phoneUtil->format($number, PhoneNumberFormat::NATIONAL);
// Output: (415) 555-2671 (for US numbers)

3. Geocoding & Metadata

// Get region code and country name
$regionCode = $phoneUtil->getRegionCodeForNumber($number);
$countryCode = $phoneUtil->getCountryCodeForNumber($number);
$countryName = $phoneUtil->getCountryNameForNumber($number);

4. Batch Processing

// Process an array of phone numbers (e.g., from a CSV import)
$numbers = ['+14155552671', '+442071838750'];
$processed = [];
foreach ($numbers as $phone) {
    $processed[] = $phoneUtil->parse($phone, null); // Auto-detect country
}

5. Integration with Laravel Validation

Create a custom rule:

use libphonenumber\PhoneNumberUtil;
use Illuminate\Contracts\Validation\Rule;

class ValidPhoneNumber implements Rule {
    protected $phoneUtil;

    public function __construct() {
        $this->phoneUtil = PhoneNumberUtil::getInstance();
    }

    public function passes($attribute, $value) {
        try {
            $number = $this->phoneUtil->parse($value);
            return $this->phoneUtil->isValidNumber($number);
        } catch (\libphonenumber\NumberParseException $e) {
            return false;
        }
    }

    public function message() {
        return 'The :attribute must be a valid phone number.';
    }
}

Usage in a Form Request:

public function rules() {
    return [
        'phone' => ['required', new ValidPhoneNumber],
    ];
}

6. Storing Normalized Numbers

Store phone numbers in E164 format (e.g., +14155552671) in the database for consistency:

$e164Number = $phoneUtil->format($number, PhoneNumberFormat::E164);
$user->phone = $e164Number;
$user->save();

Laravel-Specific Tips

Service Provider Binding

Register the PhoneNumberUtil as a singleton in AppServiceProvider:

public function register() {
    $this->app->singleton(PhoneNumberUtil::class, function () {
        return PhoneNumberUtil::getInstance();
    });
}

Now inject it into controllers/services:

public function __construct(private PhoneNumberUtil $phoneUtil) {}

Caching the PhoneNumberUtil Instance

Since PhoneNumberUtil::getInstance() is thread-safe, cache it in Laravel’s cache:

$phoneUtil = Cache::remember('phone-number-util', 365 * 24 * 60, function () {
    return PhoneNumberUtil::getInstance();
});

Gotchas and Tips

Pitfalls

  1. Country Code Ambiguity:

    • Parsing without a country code (e.g., parse('02071838750')) may fail or return unexpected results.
    • Fix: Always specify a country code if possible, or handle NumberParseException.
  2. Time Zone Data:

    • The library relies on Google’s time zone and geocoding data, which is updated periodically.
    • Fix: Ensure your vendor directory is up-to-date (composer update).
  3. Short Numbers vs. Full E164:

    • Short numbers (e.g., 5552671) may not parse correctly without a country code.
    • Fix: Prepend +1 or the appropriate country code before parsing.
  4. Non-Standard Formats:

    • Some countries use non-standard formats (e.g., 0 prefix in the UK).
    • Fix: Use PhoneNumberFormat::NATIONAL for display, but store in E164.
  5. Performance with Large Datasets:

    • Parsing thousands of numbers sequentially can be slow.
    • Fix: Use batch processing or parallelize with Laravel Queues.

Debugging Tips

  1. Check Parsing Errors:

    try {
        $number = $phoneUtil->parse($input);
    } catch (\libphonenumber\NumberParseException $e) {
        \Log::error("Phone parse error: " . $e->getMessage());
    }
    
  2. Validate Before Storing:

    if (!$phoneUtil->isValidNumber($number)) {
        throw new \RuntimeException("Invalid phone number: " . $phoneUtil->format($number));
    }
    
  3. Log Unexpected Formats:

    $formats = [
        PhoneNumberFormat::E164,
        PhoneNumberFormat::INTERNATIONAL,
        PhoneNumberFormat::NATIONAL,
    ];
    foreach ($formats as $format) {
        \Log::debug("Formatted ($format): " . $phoneUtil->format($number, $format));
    }
    

Extension Points

  1. Custom Formatters: Extend the library to add domain-specific formatting:

    class CustomPhoneFormatter {
        public static function formatForAPI($number) {
            $util = PhoneNumberUtil::getInstance();
            $formatted = $util->format($number, PhoneNumberFormat::E164);
            return str_replace('+', '', $formatted); // Remove '+' for API consistency
        }
    }
    
  2. Database Migration Helpers: Create a trait for phone number handling in Eloquent models:

    trait HandlesPhoneNumbers {
        public function getPhoneNumberAttribute($value) {
            if (empty($value)) return null;
            $util = PhoneNumberUtil::getInstance();
            return $util->parse($value, null);
        }
    
        public function setPhoneNumberAttribute($value) {
            $util = PhoneNumberUtil::getInstance();
            $this->attributes['phone_number'] = $util->format($util->parse($value), PhoneNumberFormat::E164);
        }
    }
    
  3. Testing: Use libphonenumber\PhoneNumberUtil in PHPUnit tests:

    public function testPhoneNumberValidation() {
        $util = PhoneNumberUtil::getInstance();
        $this->assertTrue($util->isValidNumber($util->parse('+14155552671')));
        $this->assertFalse($util->isValidNumber($util->parse('invalid')));
    }
    

Configuration Quirks

  1. Default Country Code: The library does not set a default country code. Always handle cases where parsing fails due to ambiguity.

  2. Locale-Specific Formatting: Use PhoneNumberFormat::RFC3966 for locale-agnostic formats (e.g., `tel:+1-415

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours