همهی راهنماها
راهنمایی با این جستوجو پیدا نشد.
مرور اعتبارسنجها
شش اعتبارسنج ایرانی چطور کار میکنند. قرارداد مشترک Validator، شیء Result، کدهای خطای پایدار، یکسانسازی ورودی و سقف اندازه.
در این صفحه
شش اعتبارسنج
RTLY-Kit برای دادههایی که برنامههای ایرانی هر روز با آنها کار میکنند شش اعتبارسنج دارد. همه ساختار یکسانی دارند. وقتی یکی را یاد بگیرید، بقیه را هم میشناسید.
| کلاس | چه چیزی را بررسی میکند | صفحه |
|---|---|---|
NationalCode | ۱۰ رقم، رقم کنترل به پیمانهٔ ۱۱، سرنخی از محل صدور | کد ملی |
Sheba | IR و ۲۴ رقم، ISO 7064 mod-97-10، پیدا کردن بانک | شبا و کارت بانکی |
BankCard | ۱۶ رقم، چکسام Luhn، تشخیص بانک از روی BIN | شبا و کارت بانکی |
Mobile | قالب 09xxxxxxxxx در پنج شکل ورودی، اپراتور و تخصیص پیششماره | موبایل، کدپستی، پلاک |
PostalCode | ۱۰ رقم، رقم اول غیر از 0 | موبایل، کدپستی، پلاک |
VehiclePlate | قالب پلاک سواری، تقسیمشده به بخشها | موبایل، کدپستی، پلاک |
همه در فضاینام RtlyKit\Validation هستند. رقمهای فارسی و عربی را همانطور که کاربر تایپ کرده قبول میکنند. پس ورودی فرم را بدون تمیزکاری مستقیم به آنها بدهید.
دو راه برای صدا زدن
هر اعتبارسنج هم جواب بولی میدهد و هم جواب کامل. اگر فقط «بله یا نه» میخواهید، isValid() را بزنید. اگر میخواهید دلیل رد شدن را به کاربر بگویید، validate() را بزنید.
<?php
require 'vendor/autoload.php';
use RtlyKit\Validation\NationalCode;
use function RtlyKit\is_national_code;
var_dump(NationalCode::isValid('۰۴۹۹۳۷۰۸۹۹')); // bool(true)
var_dump(is_national_code('0499370899')); // bool(true)
$result = NationalCode::validate('0499370898');
var_dump($result->isValid()); // bool(false)
print_r($result->errors()); // Array ( [0] => invalid_checksum )توابع کمکی (is_national_code()، validate_sheba() و مانند اینها) در فضاینام خودشان هستند و با use function RtlyKit\is_national_code; وارد میشوند. نامهای کوتاه سراسری اختیاری است. توابع کمکی و سراسری را ببینید.
قرارداد Validator
هر اعتبارسنج اینترفیس RtlyKit\Contracts\Validator را پیاده میکند. این اینترفیس دو متد استاتیک دارد:
validate(mixed $value): ResultisValid(mixed $value): bool، که کوتاهشدهٔvalidate($value)->isValid()است
اعتبارسنجها حالت ندارند و برای همین استاتیکاند. پس میتوانید اعتبارسنج را موقع اجرا با class-string انتخاب کنید، مثلاً از روی یک آرایهٔ تنظیمات:
use RtlyKit\Contracts\Validator;
use RtlyKit\Validation\Mobile;
use RtlyKit\Validation\NationalCode;
use RtlyKit\Validation\PostalCode;
/** @var array<string, class-string<Validator>> $rules */
$rules = [
'national_code' => NationalCode::class,
'mobile' => Mobile::class,
'postal' => PostalCode::class,
];
$input = ['national_code' => '0499370899', 'mobile' => '0912', 'postal' => '1234567890'];
foreach ($rules as $field => $class) {
$result = $class::validate($input[$field]);
echo $field, ': ', $result->isValid() ? 'ok' : implode(',', $result->errors()), "\n";
}
// national_code: ok
// mobile: invalid_format
// postal: okخطا پرتاب نمیکند. هیچکدام از این دو متد برای ورودی بد خطا نمیدهد. هر مقداری، از null و آرایه و شیء تا رشتهٔ خیلی بلند و UTF-8 خراب، یک Result نامعتبر با کد خطای پایدار میدهد. خطا فقط برای اشتباه برنامهنویس در بخشهای دیگر کتابخانه است. مدیریت خطا را ببینید.
شیء Result
RtlyKit\Validation\Result یک مقدار تغییرناپذیر با سه متد خواندن است:
| متد | خروجی |
|---|---|
isValid() | bool |
errors() | list<string>. کدهای خطای پایدار. اگر معتبر باشد خالی است |
details() | array<string, mixed>. چیزهایی که اعتبارسنج در راه فهمیده |
جزئیات هم برای نتیجهٔ معتبر هست و هم برای نامعتبر (تا هر جا که اعتبارسنج جلو رفته باشد). پس میتوانید کنار پیام خطا، مقدار یکسانشده یا نام بانک را هم نشان بدهید:
use RtlyKit\Validation\BankCard;
$result = BankCard::validate('6037991234567890');
var_dump($result->isValid()); // bool(false)
print_r($result->errors()); // Array ( [0] => invalid_checksum )
echo json_encode($result->details(), JSON_UNESCAPED_UNICODE);
// {"normalized":"6037991234567890","bin":"603799","bank_name":"بانک ملی ایران"}کلیدهای جزئیات هر اعتبارسنج
| اعتبارسنج | کلیدهای جزئیات |
|---|---|
NationalCode | normalized، location ({province, city} یا null) |
Sheba | normalized، bank_code، bank_name |
BankCard | normalized، bin، bank_name |
Mobile | normalized، operator، allocated (bool) |
PostalCode | normalized |
VehiclePlate | normalized و، اگر قالب بخورد: two_digit، letter، three_digit، region |
مقدارهایی که از جدول میآیند (location، bank_name، operator) اگر ردیفی پیدا نشود null هستند. پیدا نشدن یعنی «نمیدانیم»، نه «نامعتبر».
کدهای خطا
کدهای خطا پایدار و ماشینخواناند و بین نسخهها عوض نمیشوند. میتوانید هر کدام را به پیام یا ترجمهٔ خودتان وصل کنید. بخش Laravel هم دقیقاً همین کار را میکند. اعتبارسنجی و cast در Laravel را ببینید.
| کد | معنا | کجا میآید |
|---|---|---|
invalid_type | مقدار رشته، عدد صحیح یا عدد اعشاریِ صحیح و متناهی نیست | همه |
input_too_long | رشته از ۴۰۹۶ بایت بلندتر است | همه |
invalid_format | شکل ورودی درست نیست (نویسهها، تعداد رقم، الگو) | همه. در PostalCode برای رقم اول 0 |
invalid_length | تعداد رقمها ۱۰ نیست | PostalCode |
repeated_digits | همهٔ رقمها یکی هستند (1111111111) | NationalCode، BankCard |
invalid_checksum | رقم کنترل جور درنمیآید | NationalCode، Sheba، BankCard |
invalid_region | یکی از بخشهای عددیِ پلاک همه صفر است | VehiclePlate |
الان هر نتیجه حداکثر یک خطا دارد (اولین بررسی که رد شد). ولی errors() فهرست میدهد تا بعداً بشود چند خطا را با هم گزارش کرد.
ورودی چطور پردازش میشود
پیش از هر قاعده، مقدار از یک مرحلهٔ مشترک رد میشود:
- رشتهها تا ۴۰۹۶ بایت قبول میشوند. هر رقم فارسی یا عربی دو بایت است، پس سقف حدود ۲۰۰۰ رقم از این نوع است. رشتهٔ بلندتر
input_too_longمیدهد. intبا(string)به رشته تبدیل میشود.floatباید متناهی و صحیح باشد و قدرمطلقش از 10 15 کمتر باشد. بدون نمای علمی به رشته تبدیل میشود.NaN،INF،1.5و عددهای خیلی بزرگinvalid_typeمیدهند.- بقیه، یعنی
null،bool، آرایه و شیء،invalid_typeمیدهند.
use RtlyKit\Validation\NationalCode;
use RtlyKit\Validation\PostalCode;
print_r(NationalCode::validate(null)->errors()); // [invalid_type]
print_r(NationalCode::validate(1.5)->errors()); // [invalid_type]
print_r(NationalCode::validate(str_repeat('1', 4097))->errors()); // [input_too_long]
print_r(NationalCode::validate("\xff\xfe")->errors()); // [invalid_format]
var_dump(PostalCode::validate(1234567890)->isValid()); // bool(true)صفر اول و عدد صحیح. اگر کد ملی یا کدپستی را عدد صحیح بدهید، صفرهای اولش از بین میرود. 499370899 با 0499370899 یکی نیست و اعتبارسنج فقط نه رقم میبیند. این شمارهها را از فرم یا ستون پایگاه داده تا اعتبارسنج به شکل رشته نگه دارید.
یکسانسازی
بعد از آن مرحله، هر اعتبارسنج رشته را با متد عمومی normalize() خودش یکسان میکند. قاعدههای مشترک:
- رقمهای فارسی (
۰-۹) و عربی-هندی (٠-٩) باDigits::toEnglish()انگلیسی میشوند. - جداکنندههایی که کاربر میتایپد حذف میشوند: فاصله، خط تیره و نیمفاصله (ZWNJ).
MobileوBankCardوPostalCodeبیشتر پاک میکنند و فقط رقمها را نگه میدارند. - در
Shebaحروف بزرگ میشوند و اگر فقط ۲۴ رقم باشد، پیشوندIRاضافه میشود.
مقدار یکسانشده همیشه در details()['normalized'] هست. همان را ذخیره کنید، نه ورودی خام را. اینطور یک شماره هیچوقت با دو املای مختلف ذخیره نمیشود.
جدولهای جستوجو و منبع داده
چهار اعتبارسنج یک جستوجو هم دارند: بانک از روی BIN کارت، بانک از روی کد شبا، محل صدور از روی پیششمارهٔ کد ملی و اپراتور از روی پیششمارهٔ موبایل. اینها امکان کمکیاند و معتبر بودن به آنها بستگی ندارد.
- BIN کارت بانکی: ۳۹ مورد. کد بانک در شبا: ۳۸ مورد. پیششمارهٔ کد ملی: ۵۴۷ مورد.
- هر مورد وقتی وارد جدول میشود که دستکم دو منبع مستقل با هم موافق باشند. اگر مورد در جدول نباشد، یعنی ناشناخته است.
- کد بانکهای شبا با مشخصات رسمی IBAN که بانک مرکزی منتشر کرده (۱۹ کد) برابر است. بقیهٔ جدولها از چند صفحهٔ عمومی گرفته شدهاند و با هم سازگارند.
خوب است بدانید. بانکها ادغام میشوند، نامشان عوض میشود و شمارهها قابل انتقال بین اپراتورها هستند. پس نتیجهٔ جستوجو را به شکل «اشاره» نشان دهید و تصمیم مالی یا حقوقی را روی آن بنا نکنید. منبعها و تاریخ بررسیها در دقت و داده است.
ادامه
- کد ملی : الگوریتم، یکسانسازی و محل صدور.
- شبا و کارت بانکی : mod-97 و Luhn و تشخیص بانک.
- موبایل، کدپستی و پلاک خودرو .
- سقفها : همهٔ سقفهای اندازه در یک صفحه.
این صفحه مفید بود؟