كشف فشل في تسجيل الدخول، تبيّن أن سببه عدم تطابق في تخزين أرقام الهواتف، عن خلل تقني. تم حظر حساب أحد المستخدمين لأن قاعدة البيانات كانت تحتوي على نفس رقم الهاتف الألماني بصيغتين مختلفتين — 0171 5550134 في صف، و +49 171 5550134 في صف آخر — مما جعل النظام يتعامل معهما كمدخلين منفصلين. والنتيجة: لم يصل رمز التحقق (OTP) أبدًا، وأصبح زر "إرسال الرمز" بمثابة مقامرة.
لماذا تُعد أرقام الهواتف أصعب من التواريخ
غالبًا ما يثق المطورون في التعبيرات النمطية (regex) لضبط مدخلات أرقام الهواتف. لكن هذه الثقة تنهار في اللحظة التي يعبر فيها الرقم حدودًا دولية أو يتغير فيها المخطط الوطني للاتصالات. تتبع التواريخ تقويمًا يمكن التنبؤ به؛ أما أرقام الهواتف فتتغير بتغير شركات الاتصالات، واللوائح، والتقاليد الثقافية.
التكلفة الخفية للسلاسل النصية الخام
يبدو تخزين رقم الهاتف كسلسلة نصية بسيطة أمرًا فريدًا — حتى تشير صيغتان مختلفتان إلى نفس السطر. فأنظمة الـ OTP التي تستعلم من قاعدة البيانات عن "الرقم" تنتهي بإرسال الرمز إلى نسخة مكررة لا تصل أبدًا إلى المستخدم.
وتتفاقم المشكلة عندما تُخزن الأرقام في حقول رقمية. فعمود من نوع BIGINT يحذف علامة + وأي أصفار بادئة، مما يحول +49 171 5550134 إلى 491715550134. وبدون علامة الزائد، يصبح إعادة بناء التنسيق الأصلي مجرد تخمين.
معيار E.164
يحدد المخطط الدولي لترقيم الهواتف، E.164، تمثيلًا واحدًا وقابلًا للنقل:
- يبدأ بـ
+ - يليه رمز الدولة المكون من رقم إلى 3 أرقام
- ثم رقم المشترك
- لا يتجاوز 15 رقمًا في المجمل
- لا توجد مسافات أو نقاط أو شرطات
معيار E.164 لا يضمن أن الرقم نشط؛ بل يضمن فقط أن السلسلة النصية تتبع نمطًا هيكليًا صالحًا. تعامل معه كعقد للتنسيق، وليس كأداة للتأكد من إمكانية الاتصال.
عثرات شائعة لا يمكن للـ regex إصلاحها
- التخزين الرقمي – يحذف
BIGINTعلامة+والأصفار البادئة. استخدم عمودًا نصيًا (TEXTأوVARCHAR) بدلاً من ذلك. - التعبيرات النمطية (regex) الثابتة – تتغير الخطط الوطنية. فقد ألغت المكسيك البادئة الخاصة بها في عام 2019؛ وتتطلب الأرجنتين الآن الرقم
9بعد رمز الدولة لخطوط الهاتف المحمول. لذا تصبح الأنماط الثابتة قديمة بسرعة. - الحذف العشوائي للأصفار – تحتفظ الخطوط الأرضية الإيطالية بصفر بادئ، بينما لا تفعل الخطوط الألمانية ذلك. لذا فإن قاعدة "إزالة الأصفار البادئة" الشاملة ستفسد البيانات الإيطالية بينما تترك الأرقام الألمانية دون تغيير.
- افتراض أن التنسيق يعني إمكانية التسليم – تقوم مكتبة
libphonenumberبالتحقق من الهيكل، لكنها لا تستطيع معرفة ما إذا كان الجهاز يعمل أو ما إذا كان الرقم قد تم نقله إلى مشغل آخر.
بناء مسار بيانات موثوق
- اطلب تحديد الدولة – أضف منتقي دول في نماذج التسجيل ومرر تلك المنطقة إلى المحلل (parser).
- اعرض التنسيق المباشر – استخدم تنسيق "AsYouType" ليرى المستخدمون النمط الصحيح أثناء الكتابة.
- التحقق عند فقدان التركيز (on blur) – قم بإجراء التحقق بعد أن يغادر المستخدم الحقل بدلاً من كل ضغطة مفتاح؛ فهذا يقلل من الإزعاج.
- احفظ سلسلة E.164 فقط – قم بتخزين الرقم الموحد الذي يبدأ بـ
+في قاعدة البيانات. - التنسيق عند الواجهة – أعد التحويل إلى تخطيط سهل القراءة للبشر فقط في واجهة المستخدم (UI) أو قوالب البريد الإلكتروني.
عند ترحيل البيانات القديمة، احتفظ بالصفوف التي تفشل في عملية التحقق. قم بتحليل كل مدخل موجود في عمود جديد، وحدد الإخفاقات، وأنشئ تقريرًا. فعمليات الحذف الصامتة تؤدي إلى تذاكر دعم فني تتحول لاحقًا إلى إصلاحات مكلفة.
قائمة مراجعة سريعة للمطورين
- قم بتخزين الأرقام بتنسيق
TEXT/VARCHARوفق معيار E.164. - استخدم مكتبة Google libphonenumber؛ فهي تتعامل مع الواقع المعقد للخطط العالمية.
- وفر منطقة افتراضية للمستخدمين الذين يتجاهلون رمز الدولة.
- استدعِ
is_valid_numberلعمليات التسجيل المباشرة؛ فهي تتحقق من مطابقة الرقم للقواعد الإقليمية. - استخدم
is_possible_numberعند تنظيف البيانات الضخمة؛ فهي تلتقط المدخلات المشوهة بوضوح دون رفض الحالات الحدية.
إن التعامل الصحيح مع أرقام الهواتف ليس مجرد ميزة إضافية، بل هو شرط أساسي لأي نظام يعتمد على التواصل الموثوق مع المستخدمين. من خلال التوحيد وفق معيار E.164 وتفويض عملية التحليل لمكتبة مجربة، يزيل المطورون فئة من الأخطاء التي تآكل الثقة والإيرادات بصمت. تعامل مع أرقام الهواتف كبيانات مهيكلة، وليس كنصوص حرة، واترك المعايير تقوم بالعمل الشاق.
