در این صفحه
شش اعتبارسنج#
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باید متناهی و صحیح باشد و قدرمطلقش از 1015 کمتر باشد. بدون نمای علمی به رشته تبدیل میشود.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 و تشخیص بانک.
- موبایل، کدپستی و پلاک خودرو.
- سقفها: همهٔ سقفهای اندازه در یک صفحه.