في هذه الصفحة
أدوات التحقق الست#
تضم RTLY-Kit ست أدوات تحقق للبيانات التي تتعامل معها التطبيقات الإيرانية كل يوم. وكلها تتبع شكلًا واحداً، فإذا عرفت واحدة منها عرفت الباقي.
| الصنف | ما يتحقق منه | الصفحة |
|---|---|---|
NationalCode | 10 أرقام، ورقم تحقق بطريقة mod-11، وتلميح بمكان الإصدار | الرقم الوطني |
Sheba | IR + 24 رقماً، وفق ISO 7064 mod-97-10، مع البحث عن المصرف | شبا والبطاقة المصرفية |
BankCard | 16 رقماً، ومجموع تحقق Luhn، والبحث عن المصرف عبر BIN | شبا والبطاقة المصرفية |
Mobile | صيغة 09xxxxxxxxx في خمسة أشكال للإدخال، وتلميح بالمشغّل | الجوال والرمز البريدي واللوحة |
PostalCode | 10 أرقام، والرقم الأول ليس 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، وفيها دالتان ساكنتان (static) فقط:
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 بالضبط؛ راجع قواعد التحقق والتحويل في Laravel.
| المفتاح | المعنى | يستخدمه |
|---|---|---|
invalid_type | القيمة ليست سلسلة نصية ولا عددًا صحيحًا ولا عددًا عشريًا صحيحًا منتهيًا | الجميع |
input_too_long | سلسلة نصية أطول من 4096 بايت | الجميع |
invalid_format | الصيغة خاطئة (مجموعة المحارف أو عدد الأرقام أو النمط) | الجميع عدا PostalCode، التي تستخدمه عند وجود 0 في البداية |
invalid_length | عدد الأرقام ليس 10 | PostalCode |
repeated_digits | جميع الأرقام متماثلة (1111111111) | NationalCode، BankCard |
invalid_checksum | رقم التحقق أو أرقام التحقق لا تطابق | NationalCode، Sheba، BankCard |
invalid_region | جزء رقمي من اللوحة كله أصفار | VehiclePlate |
تحمل النتيجة اليوم خطأً واحدًا على الأكثر (أول فحص فشل)، لكن errors() تُرجع قائمة كي تتمكن فحوصات مستقبلية من الإبلاغ عن عدة أخطاء.
معالجة المدخلات#
قبل تشغيل أي قاعدة، تمرّ القيمة عبر بوابة مشتركة واحدة:
- السلاسل النصية حتى 4096 بايت تمرّ. يشغل الرقم الفارسي أو العربي بايتين، فالحد الأقصى نحو 2000 رقم من هذا النوع. والسلسلة الأطول تُنتج
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إلى سلسلة مجردة من 24 رقمًا.
تُرجَع القيمة المطبَّعة دائمًا في details()['normalized']. خزّنها هي لا المدخل الخام، كي لا يُحفظ الرقم نفسه بصيغتين.
جداول البحث ومصادرها#
تُرفق أربع أدوات تحقق معلومة بحث: المصرف من BIN البطاقة، والمصرف من رمز شبا، ومكان الإصدار من بادئة الرقم الوطني، والمشغّل من بادئة الجوال. هذه البيانات مجرد إضافة مريحة فوق التحقق؛ أما الصلاحية نفسها فلا تعتمد عليها أبدًا.
- BIN البطاقات المصرفية: 39 مدخلًا. رموز المصارف في شبا: 38 مدخلًا. بادئات الرقم الوطني: 547 مدخلًا.
- رموز المصارف الـ 19 الواردة في مواصفة IBAN المنشورة لدى البنك المركزي الإيراني تطابق جدول المكتبة. أما بقية الجداول فتتفق مع عدة صفحات عامة، لأن قائمة رسمية لم تتوفر.
- المدخل غير الموجود في الجدول يعني «غير معروف»، ولا يعني «غير صالح».
إلى أين تذهب بعد ذلك#
- الرقم الوطني: الخوارزمية والتطبيع وتلميح مكان الإصدار.
- شبا والبطاقة المصرفية: mod-97 وLuhn والبحث عن المصارف.
- الجوال والرمز البريدي ولوحة المركبة.
- الحدود: كل حدود الحجم في مكان واحد.