Laravelで電話番号を扱うためのライブラリ

Laravelで電話番号を扱うためのライブラリ

電話番号って一見簡単そうに思えて、かなり難しいデータ書式だと思います。

国によって違うのは当たり前で、日本国内でも、形式は色々で、一般的に多いのはxxx-xxxx-xxxxやxxx-xxx-xxxxですが、xx-xxxxx-xxxx、xxxx-xx-xxxxなど、その地域の人しか見たことのないような書式のものもあります。

そのため、僕は電話番号のバリデーションやフォーマットの変更などは難易度が高くで嫌いでした。

先日、Google’s libphonenumber API を使用した Laravel Phone というLaravel用のライブラリを見つけ、簡単に電話番号のバリデーションやフォーマットができたため、ご紹介したいと思います。

Laravel Phone

Laravel Phone は、Google’s libphonenumber API を利用したLaravel用の電話番号処理ライブラリです。

デモサイト

Laravel Phoneにはデモサイトがあり、バリデーション結果などを確認することができます。また、Laravel Phoneの元となっているlibphonenumber for PHPにもデモサイトがあり、バリデーション結果やフォーマット結果などを確認することができます。

インストール

Laravel Phoneは、composerでインストール可能です。

$ composer require propaganistas/laravel-phone

翻訳ファイル

バリデーションエラーのメッセージは、翻訳ファイル(validation.php)で変更できます。

return [
    // ...

    'phone' => ':attributeに有効な電話番号を指定してください。',
];

基本的な使い方

バリデーション

バリデーションは、以下のように設定します。

'phonefield' => 'phone:JP',
'phonefield' => 'phone:US,JP',
'phonefield' => 'phone:AUTO,JP',

バリデーションの引数は、国の識別コードで複数指定可能です。AUTOを指定することで国の識別ナンバーがある場合は、その国の電話番号として扱うようになります。電話番号のフォーマットは、e164やRFC3966など複数のものに対応しています。

属性のキャスト

Modelの属性をPropaganistas\LaravelPhone\PhoneNumberにキャストすることができます。

use Illuminate\Database\Eloquent\Model;
use Propaganistas\LaravelPhone\Casts\RawPhoneNumberCast;
use Propaganistas\LaravelPhone\Casts\E164PhoneNumberCast;

class User extends Model
{
    public $casts = [
        'phone' => RawPhoneNumberCast::class.':AUTO,JP',
        'another_phone' => E164PhoneNumberCast::class.':AUTO,JP',
    ];
}

ユーティリティクラス

Propaganistas\LaravelPhone\PhoneNumbeは、複数のフォーマットに対応しています。

use Propaganistas\LaravelPhone\PhoneNumber;

PhoneNumber::make('012 34 56 78', 'BE')->format($format);       // See libphonenumber\PhoneNumberFormat
PhoneNumber::make('012 34 56 78', 'BE')->formatE164();          // +3212345678
PhoneNumber::make('012 34 56 78', 'BE')->formatInternational(); // +32 12 34 56 78
PhoneNumber::make('012 34 56 78', 'BE')->formatRFC3966();       // +32-12-34-56-78
PhoneNumber::make('012/34.56.78', 'BE')->formatNational();      // 012 34 56 78

// Formats so the number can be called straight from the provided country.
PhoneNumber::make('012 34 56 78', 'BE')->formatForCountry('BE'); // 012 34 56 78
PhoneNumber::make('012 34 56 78', 'BE')->formatForCountry('NL'); // 00 32 12 34 56 78
PhoneNumber::make('012 34 56 78', 'BE')->formatForCountry('US'); // 011 32 12 34 56 78

// Formats so the number can be clicked on and called straight from the provided country using a cellphone.
PhoneNumber::make('012 34 56 78', 'BE')->formatForMobileDialingInCountry('BE'); // 012345678
PhoneNumber::make('012 34 56 78', 'BE')->formatForMobileDialingInCountry('NL'); // +3212345678
PhoneNumber::make('012 34 56 78', 'BE')->formatForMobileDialingInCountry('US'); // +3212345678

Faker対応

FakerのphoneNumberは、国の指定などができず、バリデーションエラーとなってしまうため、以下のようなコードを自作してお茶を濁す必要があります。

use Faker\Provider\Base as BaseProvider;
use Propaganistas\LaravelPhone\PhoneNumber as LaravelPhoneNumber;

class PhoneNumber extends BaseProvider
{
    public function validE164PhoneNumber(): string
    {
        $result = null;

        while (!$result) {
            try {
                $result = LaravelPhoneNumber::make($this->generator->e164PhoneNumber)->formatE164();
            } catch (\Exception) {
                // Do nothing
            }
        }

        return $result;
    }
}

終わりに

今回、Laravelで電話番号をバリデーションするためのライブラリをご紹介しましたが、顧客リストのような、電話番号を記録するだけのシステム(SMSなどを送ったりしないシステム)でバリデーションを行うと、入力データの自由度が下がるだけなので、バリデーションは不要なのかもとも考えさせられました…

しかし、仕様変更などを考慮するとはじめからバリデーションをしておいた方が良いかと思います。

参考サイト