Skip to content
Devix Open Source

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 wherePhone scope, masked(), whatsappUrl(), and a request macro.
Updated 15 Sep 2026