نظرة عامة على أدوات التحقق

كيف تعمل أدوات التحقق الإيرانية الست: عقد Validator المشترك، وكائن Result، ومفاتيح الأخطاء الثابتة، وتطبيع المدخلات وحدود الحجم.

في هذه الصفحة
  1. أدوات التحقق الست
  2. طريقتان للاستدعاء
  3. عقد Validator
  4. كائن Result
    1. مفاتيح التفاصيل لكل أداة تحقق
  5. مفاتيح الأخطاء
  6. معالجة المدخلات
  7. التطبيع
  8. جداول البحث ومصادرها
  9. إلى أين تذهب بعد ذلك

أدوات التحقق الست#

تضم RTLY-Kit ست أدوات تحقق للبيانات التي تتعامل معها التطبيقات الإيرانية كل يوم. وكلها تتبع شكلًا واحداً، فإذا عرفت واحدة منها عرفت الباقي.

الصنفما يتحقق منهالصفحة
NationalCode10 أرقام، ورقم تحقق بطريقة mod-11، وتلميح بمكان الإصدارالرقم الوطني
ShebaIR + 24 رقماً، وفق ISO 7064 mod-97-10، مع البحث عن المصرفشبا والبطاقة المصرفية
BankCard16 رقماً، ومجموع تحقق Luhn، والبحث عن المصرف عبر BINشبا والبطاقة المصرفية
Mobileصيغة 09xxxxxxxxx في خمسة أشكال للإدخال، وتلميح بالمشغّلالجوال والرمز البريدي واللوحة
PostalCode10 أرقام، والرقم الأول ليس 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): Result
  • isValid(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":"بانک ملی ایران"}

مفاتيح التفاصيل لكل أداة تحقق#

أداة التحققمفاتيح التفاصيل
NationalCodenormalized، location ({province, city} أو null)
Shebanormalized، bank_code، bank_name
BankCardnormalized، bin، bank_name
Mobilenormalized، operator، allocated (قيمة bool: هل تقع بادئة الرقم في خطة الترقيم المنشورة للهاتف المحمول)
PostalCodenormalized
VehiclePlatenormalized، وعند مطابقة الصيغة: 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عدد الأرقام ليس 10PostalCode
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 المنشورة لدى البنك المركزي الإيراني تطابق جدول المكتبة. أما بقية الجداول فتتفق مع عدة صفحات عامة، لأن قائمة رسمية لم تتوفر.
  • المدخل غير الموجود في الجدول يعني «غير معروف»، ولا يعني «غير صالح».
من المفيد أن تعرف. نتيجة البحث تلميح مفيد وليست سجلًا رسميًا. المصارف تندمج وتغيّر أسماءها، ويمكن نقل رقم الجوال بين المشغّلين. لذلك اعرض النتيجة على أنها معلومة إرشادية، ولا تبنِ عليها قرارًا قانونيًا أو ماليًا. تجد المصادر والتواريخ في الدقة والبيانات.

إلى أين تذهب بعد ذلك#