2.4التواريخ والتعابير النمطية (Regex) والرسائل الإلكترونية
الأساسي في 30 ثانية
- التواريخ بـ DateTime : إنشاء وتنسيق عند العرض (->format) وحساب الفروق (->diff) — المنطقة مضبوطة وإلا الساعات خاطئة.
- خزن ISO واعرض محليا : نخزن AAAA-MM-JJ (قابل للترتيب وغير ملتبس) وننسق عند العرض فحسب — لا صيغة محلية في القاعدة أبدا.
- filter_var أولا والتعابير عند الحاجة والمكتبة للرسائل : البريد والرابط عبر filter_var، وأنماط العمل بالتعابير المختبرة، والإرسال عبر PHPMailer أو Symfony Mailer — لا mail() في إنتاج جاد أبدا.
حالة مستمرة — رياد يؤرخ ويراقب ويكتب للأعضاء
الفصل الأخير من المشروع : رياد يؤرخ التسجيلات (2.1) والصور (2.3) بـ DateTime — بعد أن أضاع ظهيرة على ساعات مزاحة بسبب المنطقة غير المضبوطة. يراقب أرقام الأعضاء (صيغة داخلية دقيقة) بتعبير مختبر، لكنه يتحقق من العناوين بـ filter_var بدل تعبير مصنوع. وللنشرة، يهجر mail() لمكتبة مخصصة تدير المصادقة وقابلية التوصيل. مشروع المستوى 2 مُسلَّم : النماذج والجلسات والملفات والتواريخ.
خاتمة الخيط الرابط 2.1-2.3 : موقع رياد يعالج التواريخ والأنماط والرسائل بالأدوات الصحيحة.
1. التواريخ : DateTime والمنطقة والتخزين
التواريخ حاضرة في كل مكان (الإنشاء، الفعاليات، المدد) وPHP الحديث يديرها كائِنيا (Orienté objet) بـ DateTime — وDateTimeImmutable المفضل لأنه غير قابل للتعديل : إنشاء (new DateTime('2026-07-25') وnew DateTime() للآن)، وتَنسيق للعرض (->format('d/m/Y'))، وحساب الفُروق (->diff() بين تاريخين، ويدير السنوات الكبيسة والشهور المتفاوتة)، وإضافة/طرح المدد. الدوال الإجرائية القديمة (date() وtime() وstrtotime()) موجودة — ستصادفها. وحذران : المنطقة الزمنية (تُضبَط صراحة وإلا أزيحت كل الساعات — فخ رياد رقم 1 ؛ وللدولي، خزن بـ UTC وحول عند العرض) وصيغة التخزين : نخزن بالصيغة المعيارية ISO (AAAA-MM-JJ، وهي أيضا للقواعد — قابلة للترتيب وغير ملتبسة) ونُنسِّق عند العرض فحسب — ولا عكس أبدا.
2. التعابير : قوية لكن ليست لكل شيء
التعابير النمطية (Regex) تصف أَنماطا في النص : التحقق من صيغة (الرمز البريدي، مرجع العمل)، واستخراج أجزاء، والاستبدال حسب نمط. وفي PHP : preg_match() (هل يطابق ؟)، وpreg_match_all()، وpreg_replace()، وpreg_split(). وهي قَوية لكنها صعبة السمعة (صياغة غامضة، سهلة الكتابة السيئة — صارمة جدا أو متساهلة جدا، وبطيئة أحيانا). ومن هنا القاعدة : للتحققات الشائِعة (البريد، الرابط، IP، العدد الصحيح)، لا تكتب تعبيرك — استعمل filter_var() (FILTER_VALIDATE_EMAIL وFILTER_VALIDATE_URL) المُجرَّب والموثوق (فالتحقق من بريد صحيح بتعبير صعب على نحو مدهش). واحتفظ بالتعابير للأنماط الخاصة غير المغطاة بالمرشحات — كرقم عضو رياد — باختبارها بعناية والتعليق عليها. وللمعالجات البَسيطة (البحث، الاستبدال، التقطيع)، فضل دوال السلاسل، فهي أقرأ وأسرع.
3. الرسائل : مكتبة مخصصة وترويسات مُحكَمة
الدالة الأصلية mail() أَساسية وقليلة الموثوقية (قابلية التوصيل، السبام، إعداد الخادم) : للإرسال الجاد نستعمل مَكتبات مخصصة (PHPMailer وSymfony Mailer) تدير مصادقة SMTP والمرفقات وHTML وقابلية التوصيل — أو خدمات إرسال خارجية. ونقطة أَمان : لا تُدخِل أبدا بيانات مستخدم غير مراقبة في تَرويسات رسالة (ثغرة حقن الترويسات). فنشرة رياد تذهب إذن عبر مكتبة، بترويسات مبنية من قيم مراقبة. والمبدأ العابر للقسم : الاعتماد على الأَدوات المُجرَّبة (DateTime وfilter_var ومكتبات البريد) بدل ترقيع كل شيء يدويا.
هل تعلم ؟
سطر منطقة يساوي ظهيرة تصحيح.
🔎 مثال ملموس — 🔎 مثال ملموس — تسجيل رياد، مؤرَّخ ومتحقق
DateTime + filter_var، كما عند رياد :
$d = new DateTime('2026-07-25');
echo $d->format('d/m/Y');
// التخزين : صيغة ISO 2026-07-25
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo htmlspecialchars($email, ENT_QUOTES, 'UTF-8');
}
القراءة : إنشاء التاريخ وتنسيقه، والتخزين بـ ISO، وتحقق موثوق دون تعبير مصنوع.
الدرس : اضبط المنطقة ؛ وخزن بـ ISO ونسق عند العرض.
مفردات القسم
- التواريخ (DateTime)
- PHP الحديث يعالج التواريخ بـ DateTime/DateTimeImmutable : إنشاء وتَنسيق للعرض (->format) وحساب الفروق (->diff) وإضافة/طرح.
مثال بسيط: رياد يؤرخ كل تسجيل بـ new DateTime().
ما ليس كذلك: حسابات المدد يدويا على الطوابع الزمنية.
رد فعل: معالجة تاريخ = DateTime.
- المنطقة وصيغة التخزين
- اضبط المَنطقة الزمنية (وإلا الساعات خاطئة) ؛ وخَزِّن بالصيغة المعيارية ISO (AAAA-MM-JJ) ونَسِّق عند العرض فحسب.
مثال بسيط: رياد يخزن 2026-07-25 ويعرض 25/07/2026.
ما ليس كذلك: تاريخ مُوطَّن مخزن كما هو في القاعدة.
رد فعل: خزن بـ ISO واعرض محليا.
- التعابير النمطية (Regex)
- لغة مصغرة تصف أنماطا في النص ؛ preg_match (هل يطابق ؟) وpreg_replace (الاستبدال) — قوية لكن صعبة.
مثال بسيط: رياد يراقب رقم العضو بتعبير مختبر.
ما ليس كذلك: تعبير مصنوع للتحقق من العناوين.
رد فعل: نمط خاص بالعمل = تعبير مختبر ومُعلَّق.
- filter_var للتحقق
- للتحققات الشائعة (البريد، الرابط…)، فضل filter_var (FILTER_VALIDATE_EMAIL…) على تعبير مصنوع — أكثر موثوقية.
مثال بسيط: كل بريد عضو يمر عبر FILTER_VALIDATE_EMAIL.
ما ليس كذلك: تعبير منسوخ دون اختبار للعناوين.
رد فعل: الحالة الشائعة = مرشح مُجرَّب.
- إرسال الرسائل
- الدالة الأصلية mail() أساسية وقليلة الموثوقية ؛ استعمل مكتبات مخصصة (PHPMailer وSymfony Mailer) — ولا بيانات غير مراقبة في الترويسات أبدا.
مثال بسيط: نشرة رياد تذهب عبر مكتبة بـ SMTP مُصادَق.
ما ليس كذلك: mail() حرفي لإرسالات جماعية.
رد فعل: بريد جاد = مكتبة مخصصة.
في التطبيق — تطبيقيا — التواريخ والتعابير والرسائل
- عالج التواريخ بـ DateTime : أنشئ ونسق للعرض (->format('d/m/Y')) واحسب فرقا (->diff) ؛ واضبط المنطقة الزمنية.
- تذكر : خزن التواريخ بالصيغة المعيارية (ISO) ونَسِّق عند العرض فحسب (لا تخزن صيغة مُوطَّنة أبدا).
- تحقق بـ filter_var (البريد، الرابط) بدل تعبير مصنوع ؛ واحتفظ بالتعابير (preg_match) للأنماط الخاصة.
- لإرسال رسالة بجدية، استعمل مكتبة مخصصة (PHPMailer / Symfony Mailer) بدل mail() ؛ ولا تحقن أبدا بيانات غير مراقبة في الترويسات.
نص جاهز — الدفاع عن الأدوات المُجرَّبة في مراجعة الكود (30 ثانية)
« للتواريخ أستعمل DateTime والمنطقة مضبوطة، وأخزن بـ ISO وأنسق عند العرض — انتهت الساعات المزاحة. والعناوين تمر عبر filter_var لا بتعبير مصنوع. والإرسالات تذهب عبر مكتبة بـ SMTP مُصادَق لا بـ mail(). ثلاث أدوات مُجرَّبة، صفر ترقيع. »
يُقال مع عرض خطأ المنطقة المصحح وتعبير مصنوع مستبدَل بـ filter_var.
قالب للنسخ — تاريخ وفرق وتحقق من بريد
format('d/m/Y');
$aujourdhui = new DateTime();
$ecart = $inscription->diff($aujourdhui);
echo $ecart->format('%a jours d\u2019ancienneté');
// التخزين : $inscription->format('Y-m-d H:i:s')
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo 'E-mail invalide.';
}
أقدمية عضو
رياد يحسب سنوات العضوية بـ ->diff : السنوات الكبيسة والشهور المتفاوتة مُدارة، دون حساب يدوي.
مرجع العمل
رقم العضو يتبع صيغة داخلية صارمة : تعبير مخصص مختبر على حالات حدية ومُعلَّق.
رسالة الترحيب
العنوان متحقق بـ filter_var، والإرسال عبر مكتبة SMTP : فالترحيب يصل بدل أن ينتهي في السبام.
كود إجرائي قديم
date() أو strtotime() يُصادَف في الصيانة : رياد يقرؤه ثم يهاجر إلى DateTime لكل معالجة.
✓ ممارسات جيدة
- استعمال DateTime/DateTimeImmutable ؛ وضبط المنطقة الزمنية.
- تخزين التواريخ بـ ISO والتنسيق عند العرض فحسب.
- التحقق من البريد/الرابط بـ filter_var ؛ وإرسال الرسائل عبر مكتبة مخصصة.
✗ أخطاء شائعة
- المنطقة الزمنية غير المضبوطة (الساعات المزاحة) — الفخ رقم 1.
- تخزين تاريخ بصيغة مُوطَّنة (ملتبس وغير قابل للترتيب).
- كتابة تعبير مصنوع للتحقق من بريد (صعب وغير موثوق).
النقاط الأساسية
- التَواريخ : PHP الحديث يستعمل صنف DateTime/DateTimeImmutable (إنشاء و->format للعرض و->diff للفروق). الحذر : المَنطقة الزمنية (وإلا الساعات خاطئة) وصيغة التَخزين (ISO AAAA-MM-JJ والتنسيق عند العرض فحسب).
- التَعابير (preg_match وpreg_replace) = أنماط في النص، قوية لكن صعبة. للتحققات الشائِعة (البريد، الرابط)، فضل filter_var (FILTER_VALIDATE_EMAIL) على تعبير مصنوع.
- الرَسائل : الدالة الأصلية mail() أساسية/قليلة الموثوقية ؛ استعمل مَكتبات مخصصة (PHPMailer وSymfony Mailer) للموثوقية وقابلية التوصيل.
- المبدأ العابر : الاعتماد على الأَدوات المُجرَّبة (DateTime وfilter_var ومكتبات البريد) بدل فعل كل شيء يدويا. الأمان : لا بيانات غير مراقبة في ترويسات الرسائل.
تحدي 48 ساعة — طبق غدا
أرِّخ بيانا حقيقيا بـ DateTime (المنطقة مضبوطة والتخزين بـ ISO والعرض منسق و->diff حقيقي)، واستبدل تعبير بريد مصنوعا بـ filter_var، وحضر إرسالا عبر مكتبة بدل mail().
- أستطيع معالجة تاريخ (إنشاء وتنسيق وحساب فرق) دون خطأ منطقة.
- أعرف متى أستعمل filter_var ومتى يكون التعبير مبررا.
- حضرت إرسال رسالة عبر مكتبة بترويسات مُحكَمة.
أسئلة شائعة
ما الفخاخ الشائعة مع التواريخ في PHP، وكيف أتجنبها ؟
(1) المَنطقة الزمنية غير المضبوطة (الفخ رقم 1) : ساعات مزاحة وتأريخات خاطئة. اضبطها صراحة (date_default_timezone_set() أو date.timezone) ؛ وللدولي خزن بـ UTC وحول عند العرض. (2) الخلط بين التَخزين والعَرض : لا تخزن أبدا صيغة مُوطَّنة — خزن بـ ISO (AAAA-MM-JJ القابل للترتيب وغير الملتبس والمعياري في القاعدة) ونسق عند العرض فحسب (->format('d/m/Y')). (3) الدوال القديمة (date() وstrtotime()) : فضل DateTime/DateTimeImmutable للمعالجات. (4) الحسابات اليدوية (طوابع مطروحة) : خادعة (الكبيسة والشهور المتفاوتة) — استعمل ->diff(). (5) تغيير الساعة : DateTime بالمناطق الصحيحة يديره. (6) التحليل : DateTime::createFromFormat() بصيغة دقيقة ثم التحقق.
هل أتعلم التعابير النمطية، ومتى أستعملها (أو أتجنبها) ؟
نعم، الأَساسيات — ستصادفها في كل مكان — لكن دون هوس. تُتجنَّب في : (1) التحققات الشائِعة (البريد، الرابط، IP، العدد الصحيح) — استعمل filter_var (FILTER_VALIDATE_EMAIL…) : فالتحقق من بريد بتعبير صعب على نحو مدهش، والتعابير المصنوعة صارمة جدا أو متساهلة جدا ؛ (2) المعالجات البَسيطة — فضل دوال السلاسل (str_contains وstr_replace وexplode). تُبَرَّر في : الأنماط الخاصة غير المغطاة (الصيغة الداخلية، مرجع العمل، الاستخراج الدقيق) — مختبرة بعناية (الحالات الحدية) ومُعلَّقة (غير مقروءة وإلا). المطور الجيد يعرف متى يستعمل تعبيرا ومتى يفضل الأداة المخصصة — لا تعابير في كل مكان للتباهي.
كيف أتحقق من بريد إلكتروني في PHP ؟