Guides
Migrating from propaganistas/laravel-phone
Most apps switch in a few minutes. The concepts map one to one.
Install
composer remove propaganistas/laravel-phone
composer require devix-labs/laravel-phone
Validation
| propaganistas/laravel-phone | devix-labs/laravel-phone |
|---|---|
'phone:US,BE' |
'phone:US,BE' |
'phone:mobile' |
'phone:mobile' |
'phone:!mobile' |
'phone:!mobile' |
'phone:INTERNATIONAL,BE' |
'phone:international,BE' |
'phone:LENIENT' |
'phone:lenient' |
'phone:custom_country_field' |
'phone:custom_country_field' |
(new Phone)->country(['US', 'BE']) |
Phone::rule()->country('US', 'BE') |
(new Phone)->type('mobile') |
Phone::rule()->type('mobile') or ->mobile() |
(new Phone)->notType('mobile') |
Phone::rule()->notType('mobile') |
(new Phone)->international() |
Phone::rule()->international() |
(new Phone)->lenient() |
Phone::rule()->lenient() |
(new Phone)->countryField('x') |
Phone::rule()->countryField('x') |
The <field>_country convention works the same way. Change the import from
Propaganistas\LaravelPhone\Rules\Phone to Devix\Phone\Laravel\Rules\Phone.
Your custom validation.phone message will no longer be used. Each reason now has its own message
(see Validation), so check that the new wording suits you
before you deploy.
Casts
| propaganistas/laravel-phone | devix-labs/laravel-phone |
|---|---|
E164PhoneNumberCast::class.':BE' |
AsPhoneNumber::class.':BE' |
E164PhoneNumberCast::class.':country_field' |
AsPhoneNumber::using('country_field') |
RawPhoneNumberCast::class |
AsPhoneNumber::class — stores E.164 when complete, the raw input otherwise |
Add use HasPhoneNumbers; to the model so the country no longer has to be set before the number.
Existing E.164 columns need no migration. Columns holding raw input are read correctly as they are.
With HasPhoneNumbers, each one becomes E.164 the next time its model saves.
The PhoneNumber object
| propaganistas/laravel-phone | devix-labs/laravel-phone |
|---|---|
phone($number, $country) |
PhoneNumber::parse($number, $country) |
formatE164() |
e164() |
formatInternational() |
international() |
formatNational() |
national() |
formatRFC3966() |
rfc3966() |
formatForCountry('BE') |
formatFor('BE') — national from the same country, otherwise +… international (no 00 dialling prefix) |
getType() |
type() — returns a NumberType enum |
isOfType('mobile') |
isType('mobile') |
getCountry() |
country() |
isOfCountry('BE') |
isCountry('BE') |
equals($other, $country) |
equals($other, $country) |
notEquals($other) |
! equals($other) |
formatForMobileDialingInCountry() |
not available — use e164(), which dials from any mobile |
Type names are forgiving: fixed_line, FIXED_LINE and fixed all work.
What you gain
- The browser and the server agree. Pair the package with
<x-phone-input>or@devix-labs/phone-input. - Messages give a reason instead of just "invalid".
- One less dependency tree. No libphonenumber-for-php.
- Model helpers. A
wherePhonescope,masked(),whatsappUrl(), and a request macro.
Updated 15 Sep 2026