В битриксе всегда было полно вспомогательного функционала, который часто располагался в нерелевантных местах. Например вещи, необходимые для работы с ценой, почему-то находились в модуле инфоблоков, или хранилище для адресов в модуле магазина.

На этот раз вроде все на месте. В 17.5 в битриксе появился своего рода «парсер» для номеров телефонов. А заодно вместе с ним и форматтер. Если в двух словах, то битрикс теперь может попытаться преобразовать строковое представление номера телефона в объект, а также преобразовать его обратно в строку в заранее определенном формате. Эдакая нормализация.

Назначение у функционала простое - принять строку, распознать в ней телефон и если получилось - преобразовать в один из поддерживаемых форматов. Как бонус - можно получить информацию о разных параметрах распарсенного номера телефона.

Интерфейс работы довольно прост и, в общем-то, понятен:

use Bitrix\Main\PhoneNumber\Format;
use Bitrix\Main\PhoneNumber\Parser;

$phone = '89011111111';

// Парсим номер телефона с помощью класса-парсера
$parsedPhone = Parser::getInstance()->parse($phone);

// Из объекта распарсенного телефона можно получить разное. Например код страны
echo $parsedPhone->getCountry(); // RU

// или ... опять код страны
echo $parsedPhone->getCountryCode(); // 7

// или тип номера, возможные типы:
// 'noInternationalDialling', 'areaCodeOptional', 'fixedLine',
// 'mobile', 'pager', 'tollFree', 'premiumRate', 'sharedCost',
// 'personalNumber', 'voip', 'uan', 'voicemail'
echo $parsedPhone->getNumberType(); // mobile

// Ну или оригинальный телефон, который был скормлен парсеру
echo $parsedPhone->getRawNumber(); // 89011111111

// А можно переформатировать объект телефона в один из поддерживаемых форматов
// Национальный, видимо "наш"
echo $parsedPhone->format(Format::NATIONAL);

// Международный
echo $parsedPhone->format(Format::INTERNATIONAL);

// Ну и более-менее стандартизированный по https://ru.wikipedia.org/wiki/E.164
echo $parsedPhone->format(Format::E164);

// А еще есть парсинг коротких номеров
echo Parser::getInstance()->parse('911')->format(); //9-11

Функционал используется как нормализатор для номеров телефонов в модуле рассылок.

Непонятно, как ошибки обрабатывать, да и как вообще понять, получилось у библиотеки распознать, а если нет - то почему … но это уже детали.

В общем, ничего особенного, если бы не одно но. Я уже где-то это видел )

В продукт добавляется все больше и больше полу-функций. Все эти полу-функции копируются с какого-нибудь готового решения и потом забрасываются навсегда. Вспомнить хотя бы печально известную либу BX для фронтенда, которая копирует jquery чуть менее, чем полностью и которой никто, кроме разработчиков битрикса, не пользуется. Или распиаренные Битрикс24 сайты, которые скопировали с Тильды? Список можно продолжать.

Вот и в этот раз я почуял, что я уже где-то что-то подобное видел. И вспомнил где - в https://github.com/giggsey/libphonenumber-for-php. Довольно популярная либа для парсинга и форматирования номеров. Предоставляет куда более широкие возможности, задокументирована, покрыта тестами, легко встраивается в проект с помощью composer, интернационализация и многое другое.
Интерфейс работы с либой - практически идентичен (скопировано из официального мануала):

$swissNumberStr = "044 668 18 00";
$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
try {
    $swissNumberProto = $phoneUtil->parse($swissNumberStr, "CH");
    var_dump($swissNumberProto);
} catch (\libphonenumber\NumberParseException $e) {
    var_dump($e);
}

// Produces "+41446681800"
echo $phoneUtil->format($swissNumberProto, \libphonenumber\PhoneNumberFormat::E164);

// Produces "044 668 18 00"
echo $phoneUtil->format($swissNumberProto, \libphonenumber\PhoneNumberFormat::NATIONAL);

// Produces "+41 44 668 18 00"
echo $phoneUtil->format($swissNumberProto, \libphonenumber\PhoneNumberFormat::INTERNATIONAL);

Спрашивается, зачем копировать? Вопрос риторический … Если вам немного не подходит библиотека - ну помогите вы проекту, запилите в нем недостающую фичу и встройте к себе, ведь будет дешевле, чем пилить с нуля и поддерживать полу-продукт. А встроить с composer - вообще не проблема, ведь битрикс поддерживает composer теперь официально. Эх …