libphonenumber for PHP
composer require giggsey/libphonenumber-for-php
use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
$util = PhoneNumberUtil::getInstance();
try {
$number = $util->parse('020 7946 0958', 'GB');
var_dump($util->isValidNumber($number)); // bool(true)
echo $util->format($number, PhoneNumberFormat::E164); // +442079460958
echo $util->format($number, PhoneNumberFormat::INTERNATIONAL); // +44 20 7946 0958
} catch (NumberParseException $e) {
// not a phone number at all
}
Carrier and line type with the numlookupapi API
function lookupPhone(string $number): array
{
$ch = curl_init('https://api.numlookupapi.com/v1/validate/' . rawurlencode($number));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['apikey: ' . getenv('NUMLOOKUP_API_KEY')],
CURLOPT_TIMEOUT => 10,
]);
$body = curl_exec($ch);
curl_close($ch);
return json_decode($body, true);
}
$result = lookupPhone('+14158586273');
echo $result['line_type']; // mobile
echo $result['carrier']; // AT&T Mobility LLC
With Laravel’s HTTP client:
$result = Http::withHeaders(['apikey' => config('services.numlookup.key')])
->get('https://api.numlookupapi.com/v1/validate/' . rawurlencode($phone))
->throw()
->json();
A Laravel validation rule
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
use libphonenumber\NumberParseException;
use libphonenumber\PhoneNumberUtil;
class ValidPhone implements ValidationRule
{
public function __construct(private string $defaultRegion = 'US') {}
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$util = PhoneNumberUtil::getInstance();
try {
if (! $util->isValidNumber($util->parse((string) $value, $this->defaultRegion))) {
$fail('The :attribute is not a valid phone number.');
}
} catch (NumberParseException) {
$fail('The :attribute is not a valid phone number.');
}
}
}
$request->validate(['phone' => ['required', new ValidPhone('GB')]]);
Need VoIP detection or the carrier at sign-up? Call the API in a queued job after validation and store line_type next to the E.164 number. Get a free API key.