موبایل، کدپستی و پلاک

اعتبارسنجی شمارهٔ موبایل ایران در همهٔ شکل‌های رایج، کدپستی و پلاک خودرو، همراه با اپراتور، تخصیص پیش‌شماره و تقسیم پلاک به بخش‌ها.

در این صفحه
  1. شروع سریع
  2. شمارهٔ موبایل
    1. شکل‌هایی که قبول می‌شود
    2. قاعده
    3. اپراتور
    4. تخصیص پیش‌شماره
  3. کدپستی
  4. پلاک خودرو
    1. شکل پلاک
    2. حرف‌ها
    3. خطاها

شروع سریع#

<?php
require 'vendor/autoload.php';

use RtlyKit\Validation\Mobile;
use RtlyKit\Validation\PostalCode;
use RtlyKit\Validation\VehiclePlate;
use function RtlyKit\is_mobile;
use function RtlyKit\is_postal_code;
use function RtlyKit\is_vehicle_plate;

var_dump(is_mobile('+98 912 123 4567'));          // bool(true)
var_dump(is_postal_code('۱۲۳۴۵-۶۷۸۹۰'));          // bool(true)
var_dump(is_vehicle_plate('12ب345 ایران 67'));    // bool(true)

echo Mobile::getOperator('09121234567'), "\n";    // همراه اول

هر سه قرارداد Validator را دارند. توابع کمکی‌شان validate_mobile()، validate_postal_code() و validate_vehicle_plate() هستند.

شمارهٔ موبایل#

شکل‌هایی که قبول می‌شود#

Mobile همه‌چیز را به شکل ملی 09xxxxxxxxx (۱۱ رقم) درمی‌آورد. این پنج شکل را قبول می‌کند، با رقم فارسی یا عربی و با فاصله، خط تیره یا پرانتز بین رقم‌ها:

ورودیnormalized
0912123456709121234567
912123456709121234567
98912123456709121234567
+98912123456709121234567
0098912123456709121234567
۰۹۱۲ ۱۲۳ ۴۵۶۷09121234567
(0912) 123-456709121234567

چون Mobile فقط رقم‌ها را نگه می‌دارد، هر جداکنندهٔ غیررقمی کنار می‌رود. عدد صحیح مثل 9121234567 هم قبول می‌شود. صفر اول ندارد که از دست برود، پس به شکل ۱۰ رقمی خوانده می‌شود.

قاعده#

معتبر بودن فقط بررسی شکل است. بعد از یکسان‌سازی، شماره باید با 09 شروع شود، بعد رقمی از ۰ تا ۴ یا ۹ بیاید و هشت رقم دیگر. این‌ها بلوک‌های 090x تا 094x و 099x هستند. هر چیز دیگر، مثل 0950... یا شمارهٔ ۱۰ رقمی، invalid_format می‌دهد.

$r = Mobile::validate('09121234567');
echo json_encode($r->details(), JSON_UNESCAPED_UNICODE);
// {"normalized":"09121234567","operator":"همراه اول","allocated":true}

print_r(Mobile::validate('09501234567')->errors());   // [invalid_format]
print_r(Mobile::validate('0912123456')->errors());    // [invalid_format]
echo Mobile::normalize('+98 912 123 4567');           // 09121234567

اپراتور#

details()['operator'] و Mobile::getOperator() پیش‌شماره را در یک جدول کوچک پیدا می‌کنند. همراه اول (0910 تا 0919 و 0990 تا 0994)، ایرانسل (0900 تا 0905، 0930، 0933 و 0935 تا 0939)، اسپادان (0931)، تالیا (0932)، تله‌کیش (0934)، رایتل (0920 تا 0923)، شاتل موبایل (09981 و 09982) و آپتل (09991). اگر چند پیش‌شماره جور شود، بلندترین انتخاب می‌شود. برای شمارهٔ معتبری که پیش‌شمارهٔ آن در جدول نیست، اپراتور null است:

echo Mobile::getOperator('09351234567'), "\n";           // ایرانسل
echo Mobile::getOperator('09981234567'), "\n";           // شاتل موبایل
echo Mobile::getOperator('09991012345'), "\n";           // آپتل
var_dump(Mobile::validate('09951234567')->isValid());   // bool(true)
var_dump(Mobile::getOperator('09951234567'));            // NULL، معتبر است ولی در جدول نیست
var_dump(Mobile::getOperator('09501234567'));            // NULL، شمارهٔ نامعتبر

تخصیص پیش‌شماره#

کلید allocated در details() می‌گوید پیش‌شمارهٔ شماره در بلوک‌هایی هست که سازمان تنظیم مقررات و ارتباطات رادیویی در طرح شماره‌گذاری ملی برای خدمات موبایل آورده یا نه. این طرح را به ITU اعلام کرده است. Mobile::isAllocated() همین را به شکل bool می‌دهد و فقط برای شمارهٔ خوش‌شکل true است.

var_dump(Mobile::isAllocated('09121234567'));   // bool(true)
var_dump(Mobile::isAllocated('09061234567'));   // bool(false)
var_dump(Mobile::isAllocated('0912'));          // bool(false)
echo json_encode(Mobile::validate('09061234567')->details(), JSON_UNESCAPED_UNICODE);
// {"normalized":"09061234567","operator":null,"allocated":false}
خوب است بدانید. allocated برابر false یعنی پیش‌شماره در طرح منتشرشده نیست. شاید تازه باشد. این به معنای نامعتبر بودن شماره نیست و isValid() هنوز فقط شکل را می‌سنجد. اپراتور هم فقط یک سرنخ بر پایهٔ پیش‌شماره است. چون شماره را می‌شود با تغییر اپراتور نگه داشت (MNP)، پیش‌شماره اپراتور فعلی را تضمین نمی‌کند. بلوک‌هایی که مالکشان را از دو منبع نتوانستیم تأیید کنیم در جدول اپراتور نیامده‌اند و null می‌دهند. پیام‌رسانی یا صورتحساب را روی اپراتور بنا نکنید. جزئیات در دقت و داده است.

کلیدهای جزئیات: normalized، operator و allocated. تنها کدهای خطا invalid_format، invalid_type و input_too_long هستند. تلفن ثابت و شمارهٔ بین‌المللی قبول نمی‌شود.

کدپستی#

کدپستی ایران ۱۰ رقم است و با 0 شروع نمی‌شود. PostalCode فقط رقم‌ها را نگه می‌دارد (اول رقم‌های فارسی و عربی انگلیسی می‌شوند، بعد جداکننده‌هایی مثل فاصله و خط تیره حذف می‌شوند) و طول و رقم اول را می‌سنجد:

$r = PostalCode::validate('۱۲۳۴۵-۶۷۸۹۰');
echo json_encode($r->details());   // {"normalized":"1234567890"}

print_r(PostalCode::validate('12345')->errors());          // [invalid_length]
print_r(PostalCode::validate('123456789012')->errors());   // [invalid_length]
print_r(PostalCode::validate('0123456789')->errors());     // [invalid_format]
خطامعنا
invalid_lengthتعداد رقم‌ها ۱۰ نیست
invalid_formatکد با 0 شروع می‌شود
invalid_type، input_too_longورودی چطور پردازش می‌شود را ببینید
فقط شکل. کدپستی رقم کنترل ندارد و بازهٔ منطقه هم بررسی نمی‌شود. هر کد ۱۰ رقمی که با 0 شروع نشود معتبر است، حتی اگر پست آن را نداده باشد. عدد صحیح 1234567890 هم قبول می‌شود، چون کد معتبر هیچ‌وقت با صفر شروع نمی‌شود. ولی بهتر است کدپستی را باز هم رشته نگه دارید.

پلاک خودرو#

شکل پلاک#

VehiclePlate پلاک رایج سواری را می‌شناسد: دو رقم، یک حرف، سه رقم و کد دورقمی ایران، مثل 12ب345 ایران 67. کلمهٔ «ایران»، فاصله، خط تیره، زیرخط و نیم‌فاصله نادیده گرفته می‌شود. پس همهٔ این شکل‌ها یک پلاک‌اند:

echo VehiclePlate::normalize('۱۲ ب ۳۴۵ ایران ۶۷');   // 12ب34567

$r = VehiclePlate::validate('12ب345 ایران 67');
echo json_encode($r->details(), JSON_UNESCAPED_UNICODE);
// {"normalized":"12ب34567","two_digit":"12","letter":"ب","three_digit":"345","region":"67"}

print_r(VehiclePlate::parse('12ب345 ایران 67'));
// Array ( [two_digit] => 12 [letter] => ب [three_digit] => 345 [region] => 67 )
var_dump(VehiclePlate::parse('xx'));   // NULL

حرف‌ها#

حرف باید یکی از این‌ها باشد: الف ب پ ت ث ج د ز س ش ص ط ع ف ق ک گ ل م ن و ه ی ژ. «الف» به شکل کامل هم یک حرف حساب می‌شود. D و S لاتین برای پلاک دیپلمات و ویژه قبول می‌شود. شکل‌های عربی حرف‌ها اول یکسان می‌شوند. پس ك و ي مثل ک و ی خوانده می‌شوند:

echo json_encode(VehiclePlate::validate('12ي34567')->details(), JSON_UNESCAPED_UNICODE);
// {"normalized":"12ی34567","two_digit":"12","letter":"ی","three_digit":"345","region":"67"}

var_dump(VehiclePlate::isValid('12D34567'));       // bool(true)
var_dump(VehiclePlate::isValid('12الف34567'));     // bool(true)

خطاها#

  • invalid_format: شکل پلاک نمی‌خواند (تعداد رقم اشتباه، حرف غیرمجاز یا بخش جاافتاده).
  • invalid_region: شکل می‌خواند، ولی کد ایران 00 است یا بخش دورقمی 00 یا بخش سه‌رقمی 000. بخش‌های جداشده باز هم در details() هستند.
print_r(VehiclePlate::validate('12ب345')->errors());       // [invalid_format]
print_r(VehiclePlate::validate('12ب34500')->errors());     // [invalid_region]
print_r(VehiclePlate::validate('00ب34567')->errors());     // [invalid_region]
خوب است بدانید. این اعتبارسنج شکل پلاک و صفر نبودن عددها را می‌سنجد. نمی‌داند کدام کد ایران وجود دارد یا کدام حرف برای کدام نوع خودرو است. نوع‌های دیگر پلاک (موتورسیکلت، شکل‌های قدیمی، مناطق آزاد و پلاک دولتی) پوشش داده نشده‌اند. نتیجهٔ معتبر یعنی پلاک خوش‌شکل است، نه اینکه واقعاً صادر شده باشد.

VehiclePlate::parse() چهار بخش را در آرایه می‌دهد، یا null اگر پلاک با همان قاعده‌های validate() معتبر نباشد.