propaganistas / laravel-phone
基于 Google 的 libphonenumber API,为 Laravel 添加电话号码功能。
Requires
- php: ^8.1
- giggsey/libphonenumber-for-php-lite: ^8.13.35
- illuminate/contracts: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
- illuminate/validation: ^10.0|^11.0
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.14
- orchestra/testbench: *
- phpunit/phpunit: ^10.5
- dev-master
- 5.3.2
- 5.3.1
- 5.3.0
- 5.2.0
- 5.1.1
- 5.1.0
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.x-dev
- 4.4.5
- 4.4.4
- 4.4.3
- 4.4.2
- 4.4.1
- 4.4.0
- 4.3.8
- 4.3.7
- 4.3.6
- 4.3.5
- 4.3.4
- 4.3.3
- 4.3.2
- 4.3.1
- 4.3.0
- 4.2.7
- 4.2.6
- 4.2.5
- 4.2.4
- 4.2.3
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.4
- 4.1.3
- 4.1.2
- 4.1.1
- 4.1.0
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.1.0
- 3.0.5
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 2.8.5
- 2.8.4
- 2.8.3
- 2.8.2
- 2.8.1
- 2.8.0
- 2.7.4
- 2.7.3
- 2.7.2
- 2.7.1
- 2.7.0
- 2.6.1
- 2.6.0
- 2.5.0
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.0
- 2.2.0
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.0
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.0
This package is auto-updated.
Last update: 2024-09-04 16:03:30 UTC
README
基于 PHP 版本 的 Google 的 libphonenumber,为 Laravel 添加电话号码功能。
目录
演示
查看该包在 演示 中的行为。
安装
运行以下命令安装最新适用的版本
composer require propaganistas/laravel-phone
服务提供者会自动被 Laravel 发现。
在您的语言目录中,为每个 validation.php
语言文件添加额外的翻译
'phone' => 'The :attribute field must be a valid number.',
验证
在您的验证规则数组中使用 phone
关键字,或使用 Propaganistas\LaravelPhone\Rules\Phone
规则类以表达的方式定义规则。
要限制允许的来源国家,您可以明确指定允许的国家代码。
'phonefield' => 'phone:US,BE', // 'phonefield' => (new Phone)->country(['US', 'BE'])
或者为了使事情更动态,您还可以匹配另一个包含国家代码的数据字段。例如,为了要求电话号码与提供的居住国匹配。请确保国家字段与电话字段具有相同的名称,但以 _country
结尾以自动发现,或者将您自定义的国家字段名称作为参数传递给验证器
'phonefield' => 'phone', // 'phonefield' => (new Phone) 'phonefield_country' => 'required_with:phonefield',
'phonefield' => 'phone:custom_country_field', // 'phonefield' => (new Phone)->countryField('custom_country_field') 'custom_country_field' => 'required_with:phonefield',
注意:国家代码应遵守 ISO 3166-1 alpha-2 兼容。
要支持除白名单国家外的任何有效的国际格式电话号码,请使用 INTERNATIONAL
参数。这在您期望来自特定国家的本地格式号码时非常有用,但也想接受任何其他正确输入的外国号码
'phonefield' => 'phone:INTERNATIONAL,BE', // 'phonefield' => (new Phone)->international()->country('BE')
要指定对号码类型的约束,只需将允许的类型追加到参数的末尾,例如
'phonefield' => 'phone:mobile', // 'phonefield' => (new Phone)->type('mobile')
最常见的是 mobile
和 fixed_line
,但您可以自由使用此处定义的任何类型 这里。
在类型前加上感叹号以将其列入黑名单。请注意,您不能同时使用白名单和黑名单类型。
'phonefield' => 'phone:!mobile', // 'phonefield' => (new Phone)->notType('mobile')
您还可以通过使用 LENIENT
参数启用宽松验证。启用宽松验证后,只会检查号码的长度,而不是实际的运营商模式。
'phonefield' => 'phone:LENIENT', // 'phonefield' => (new Phone)->lenient()
属性转换
提供了两个类以自动转换 Eloquent 模型属性
use Illuminate\Database\Eloquent\Model; use Propaganistas\LaravelPhone\Casts\RawPhoneNumberCast; use Propaganistas\LaravelPhone\Casts\E164PhoneNumberCast; class User extends Model { public $casts = [ 'phone_1' => RawPhoneNumberCast::class.':BE', 'phone_2' => E164PhoneNumberCast::class.':BE', ]; }
这两个类都会自动将数据库值转换为 PhoneNumber 对象以供应用程序进一步使用。
$user->phone // PhoneNumber object or null
设置值时,它们都接受字符串值或 PhoneNumber 对象。`RawPhoneNumberCast` 将数据库值转换为原始输入号码,而 `E164PhoneNumberCast` 将格式化的 E.164 电话号码写入数据库。
在RawPhoneNumberCast
的情况下,需要提示电话的国家信息,以便正确地将原始号码解析为电话对象。在E164PhoneNumberCast
的情况下,如果要设置的值不是某些国际格式,则需要提示电话国家信息,以便正确地修改值。
这两个类以相同的方式接受转换参数
- 当存在一个类似的属性,但后缀为
_country
(例如 phone_country)时,转换将自动检测并使用它。 - 提供另一个属性名称作为转换参数
- 提供一到多个国家代码作为转换参数
public $casts = [ 'phone_1' => RawPhoneNumberCast::class.':country_field', 'phone_2' => E164PhoneNumberCast::class.':BE', ];
重要提示:这两个转换都期望有效的电话号码,以便从/到PhoneNumber对象顺利转换。请在将电话号码设置在模型之前对其进行验证。有关验证电话号码的信息,请参阅验证文档。
⚠️ 属性分配和E164PhoneNumberCast
由于E164PhoneNumberCast
的特性,如果号码不是以国际格式传递,则期望有一个有效的国家属性。由于转换是按照给定值的顺序应用的,因此请确保在设置电话号码属性之前设置国家属性。否则,E164PhoneNumberCast
将遇到空的国家值并抛出意外的异常。
// Wrong $model->fill([ 'phone' => '012 34 56 78', 'phone_country' => 'BE', ]); // Correct $model->fill([ 'phone_country' => 'BE', 'phone' => '012 34 56 78', ]); // Wrong $model->phone = '012 34 56 78'; $model->phone_country = 'BE'; // Correct $model->phone_country = 'BE'; $model->phone = '012 34 56 78';
实用PhoneNumber类
可以将电话号码封装在Propaganistas\LaravelPhone\PhoneNumber
类中,以通过有用的实用方法来增强它。在视图中直接引用这些对象或在保存到数据库时,它们将优雅地降级到E.164格式。
use Propaganistas\LaravelPhone\PhoneNumber; (string) new PhoneNumber('+3212/34.56.78'); // +3212345678 (string) new PhoneNumber('012 34 56 78', 'BE'); // +3212345678
格式化
PhoneNumber可以以多种方式格式化
$phone = new PhoneNumber('012/34.56.78', 'BE'); $phone->format($format); // See libphonenumber\PhoneNumberFormat $phone->formatE164(); // +3212345678 $phone->formatInternational(); // +32 12 34 56 78 $phone->formatRFC3966(); // tel:+32-12-34-56-78 $phone->formatNational(); // 012 34 56 78 // Formats so the number can be called straight from the provided country. $phone->formatForCountry('BE'); // 012 34 56 78 $phone->formatForCountry('NL'); // 00 32 12 34 56 78 $phone->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. $phone->formatForMobileDialingInCountry('BE'); // 012345678 $phone->formatForMobileDialingInCountry('NL'); // +3212345678 $phone->formatForMobileDialingInCountry('US'); // +3212345678
号码信息
获取有关电话号码的一些信息
$phone = new PhoneNumber('012 34 56 78', 'BE'); $phone->getType(); // 'fixed_line' $phone->isOfType('fixed_line'); // true $phone->getCountry(); // 'BE' $phone->isOfCountry('BE'); // true
相等比较
检查给定的电话号码是否(不)等于另一个号码
$phone = new PhoneNumber('012 34 56 78', 'BE'); $phone->equals('012/34.56.76', 'BE') // true $phone->equals('+32 12 34 56 78') // true $phone->equals( $anotherPhoneObject ) // true/false $phone->notEquals('045 67 89 10', 'BE') // true $phone->notEquals('+32 45 67 89 10') // true $phone->notEquals( $anotherPhoneObject ) // true/false
辅助函数
该包公开了phone()
辅助函数,它返回一个Propaganistas\LaravelPhone\PhoneNumber
实例或如果提供了$format
则返回格式化的字符串
phone($number, $country = [], $format = null)
数据库考虑
免责声明:电话号码处理在每种应用程序中都相当不同。因此,下面提到的主题因此被视为一组思考起点;**不会**提供支持。
在数据库中存储电话号码始终是一个推测性话题,并且根本不存在万能的解决方案。这完全取决于您的应用程序需求。以下是一些需要考虑的事项,以及一些实现建议。您理想的数据库设置可能是以下详细说明的一些指针的组合。
唯一性
E.164格式在全球范围内唯一地识别世界各地的电话号码。它还固有地暗示了特定的国家,并且可以按原样提供给phone()
辅助。
您需要
- 一个列来存储电话号码
- 在持久化之前将电话号码格式化为E.164
示例
- 用户输入 =
012/45.65.78
- 数据库列
phone
(varchar)=+3212456578
以输入时的方式呈现电话号码
如果您存储格式化电话号码,则原始用户输入将永久丢失。这可能对向您提供自己的输入电话号码的用户有益,例如在提高用户体验方面。
您需要
- 两列来存储原始输入和相关国家
示例
- 用户输入 =
012/34.56.78
- 数据库列
phone
(varchar)=012/34.56.78
phone_country
(varchar)=BE
支持搜索
通过电话号码进行搜索可能会很快变得荒谬复杂,并且始终需要深入了解应用程序的上下文和范围。这里有一种可能的方法,涵盖了相当多的“自然”用例。
您需要
- 额外存储可搜索电话号码变体的三列
- 标准化输入(去除所有非字母字符的原始输入)
- 国家格式电话号码(去除所有非字母字符)
- E.164格式电话号码
- 可能是一个
saving()
观察器(或等效)以在持久化前预填充变体 - 使用可搜索变体的广泛搜索查询
示例
- 用户输入 =
12/34.56.78
- 观察器方法
public function saving(User $user) { if ($user->isDirty('phone') && $user->phone) { $user->phone_normalized = preg_replace('/[^0-9]/', '', $user->phone); $user->phone_national = preg_replace('/[^0-9]/', '', phone($user->phone, $user->phone_country)->formatNational()); $user->phone_e164 = phone($user->phone, $user->phone_country)->formatE164(); } }
- 数据库列
phone_normalized
(varchar)=12345678
phone_national
(varchar)=012345678
phone_e164
(varchar)=+3212345678
- 搜索查询
// $search holds the search term User::where(function($query) use ($search) { $query->where('phone_normalized', 'LIKE', preg_replace('/[^0-9]/', '', $search) . '%') ->orWhere('phone_national', 'LIKE', preg_replace('/[^0-9]/', '', $search) . '%') ->orWhere('phone_e164', 'LIKE', preg_replace('/[^+0-9]/', '', $search) . '%') });