predev-solutions / egypt-validators
Validate and parse Egyptian national IDs, mobile numbers and governorates. Framework-agnostic PHP with Laravel validation rules.
Package info
github.com/predev-solutions/egypt-validators
pkg:composer/predev-solutions/egypt-validators
Requires
- php: ^8.2
Requires (Dev)
- illuminate/translation: ^11.0|^12.0
- illuminate/validation: ^11.0|^12.0
- phpunit/phpunit: ^11.0
Suggests
- illuminate/validation: To use the Laravel validation rules
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-27 03:34:46 UTC
README
Validate and parse Egyptian national IDs, mobile numbers and governorates in PHP.
Framework-agnostic, with ready-made Laravel validation rules.
Every Egyptian product ends up writing the same regexes: is this a real national ID? is this a real mobile number? which governorate is code 21? This package does it once, properly — including Arabic-Indic digits (٠١٠...), every way people type +20, and the birth date, governorate and gender encoded in the national ID.
Install
composer require predev-solutions/egypt-validators
National ID
A national ID is 14 digits: C YYMMDD GG SSSS X — century, date of birth, governorate, serial (odd last digit = male) and a check digit.
use Predev\EgyptValidators\NationalId; NationalId::isValid('29001010101234'); // true $info = NationalId::parse('29001010101234'); $info->birthDate->format('Y-m-d'); // "1990-01-01" $info->age(); // 36 $info->governorate->nameEn(); // "Cairo" $info->governorate->nameAr(); // "القاهرة" $info->gender; // Gender::Male NationalId::parse('29002300101234'); // null — there is no 30 February
Rejects impossible dates, leap-year mistakes, unknown governorate codes and birth dates in the future.
Mobile numbers
use Predev\EgyptValidators\Mobile; Mobile::isValid('+20 101 234 5678'); // true Mobile::normalize('(+20) 10-1234-5678'); // "01012345678" Mobile::normalize('٠١٠١٢٣٤٥٦٧٨'); // "01012345678" Mobile::toE164('010 1234 5678'); // "+201012345678" Mobile::carrier('01212345678'); // Carrier::Orange
Accepts 010…, +2010…, 002010…, 2010… and 10…, with spaces, dashes, dots and parentheses. Valid prefixes are 010 Vodafone, 011 e& (Etisalat), 012 Orange and 015 WE.
Numbers can be ported between networks, so treat
carrier()as a hint, not a guarantee.
Governorates
use Predev\EgyptValidators\Governorate; Governorate::from('21')->nameEn(); // "Giza" Governorate::from('21')->nameAr(); // "الجيزة" count(Governorate::governorates()); // 27
Codes follow the national ID; 88 is used for people born abroad.
Laravel
use Predev\EgyptValidators\Carrier; use Predev\EgyptValidators\Gender; use Predev\EgyptValidators\Laravel\EgyptianMobile; use Predev\EgyptValidators\Laravel\EgyptianNationalId; $request->validate([ 'national_id' => ['required', new EgyptianNationalId()], 'phone' => ['required', new EgyptianMobile()], // optional constraints 'driver_id' => ['required', EgyptianNationalId::make()->minAge(21)], 'nurse_id' => ['required', EgyptianNationalId::make()->gender(Gender::Female)], 'wallet' => ['required', EgyptianMobile::make()->carriers(Carrier::Vodafone)], ]);
Testing
composer install
composer test
Contributing
Issues and pull requests are welcome — especially new Egyptian formats (landlines, tax registration numbers, commercial registry numbers).
License
MIT © predev. Solutions
Built by predev. Solutions — a Cairo software house building mobile apps, web platforms and brands for Egypt and the Gulf.