NOW() في PHP: حقيقة لم تكن تعرفها عن الوقت
\n\nكل مطور PHP كتب مرة على الأقل استعلام SQL مثل INSERT INTO logs (created_at) VALUES (NOW()). وهذا يعمل بشكل رائع. لكن ماذا لو أخبرتك أن استخدام دالة MySQL NOW() في كل استعلام ليس دائمًا الخيار الأمثل؟ ماذا لو كان مشروعك يعالج ملايين الاستعلامات؟ أو كنت بحاجة إلى وقت موحد للنص البرمجي بأكمله؟
في هذه المقالة، سنشرح كيفية محاكاة دالة NOW() في PHP، وكيفية تحسين أداء التطبيقات وتجنب الأخطاء الشائعة المتعلقة بالوقت. ستتعرف متى يكون بديل NOW() في PHP أسرع من الاتصال بقاعدة البيانات، وما هي المخاطر الخفية في التعامل مع المناطق الزمنية.
\n\n\n\n
1. ما هي NOW() ولماذا نحتاج إلى محاكاتها في PHP؟
\n\nNOW() هي دالة مدمجة في MySQL (وقواعد بيانات أخرى) تُرجع التاريخ والوقت الحاليين بتنسيق YYYY-MM-DD HH:MM:SS. قد يبدو الأمر بسيطًا، لكن هناك تفاصيل مهمة:
- \n
- الضغط على قاعدة البيانات: كل استدعاء لـ
NOW()هو استعلام منفصل للخادم. إذا كنت تُدخل 10,000 صف، فستُرسل 10,000 استعلام، وتنتظر الرد، ثم تُدخل البيانات. \n - توقيت غير موحد: إذا كان النص البرمجي يعمل لعدة ثوانٍ، فقد يُرجع
NOW()أوقاتًا مختلفة في استعلامات مختلفة (الفارق بالميلي ثانية، لكنه مهم للسجلات). \n - قابلية النقل: عند تغيير قاعدة البيانات (مثل PostgreSQL أو SQLite)، قد لا تعمل
NOW()أو تعمل بشكل مختلف. \n
الحل: حساب الوقت من جهة PHP وتمريره كمعامل. بهذا تحصل على وقت موحد لجميع العمليات، وتُقلل الضغط على قاعدة البيانات، وتجعل الكود عالميًا.
\n\n\n\n
2. كيفية تطبيق NOW() في PHP: ثلاث طرق مجربة
\n\n2.1. الطريقة الكلاسيكية date('Y-m-d H:i:s')
\n\nأبسط وأسرع طريقة هي استخدام الدالة المدمجة date():
<?php\n$now = date('Y-m-d H:i:s');\necho $now; // 2025-01-15 14:30:00\n?>\n\nالمميزات: تعمل في كل مكان، استهلاك ضئيل للذاكرة، لا تحتاج لتحميل كلاسات إضافية.
\nالعيوب: تعتمد على المنطقة الزمنية المحددة في ملف php.ini (date.timezone).
2.2. الطريقة الكائنية DateTime
\n\nالمعيار الحديث في PHP هو كلاس DateTime. إنه أكثر مرونة وسهولة:
<?php\n$now = new DateTime();\necho $now->format('Y-m-d H:i:s'); // 2025-01-15 14:30:00\n?>\n\nيمكنك تحديد المنطقة الزمنية بوضوح:
\n\n<?php\n$timezone = new DateTimeZone('Asia/Riyadh');\n$now = new DateTime('now', $timezone);\necho $now->format('Y-m-d H:i:s'); // 2025-01-15 17:30:00 (توقيت الرياض)\n?>\n\n2.3. الميكروثانية مع DateTimeImmutable
\n\nللقياسات الدقيقة أو السجلات عالية التفاصيل، استخدم DateTimeImmutable (لا يعدل الكائن الأصلي):
<?php\n$now = new DateTimeImmutable();\necho $now->format('Y-m-d H:i:s.u'); // 2025-01-15 14:30:00.123456\n?>\n\nنصيحة: إذا كنت تحتاج فقط إلى الوقت للإدراج في قاعدة البيانات، استخدم date() — فهو أسرع بنسبة 10-15% من DateTime.
\n\n
3. تحسين الأداء: اختبارات ومقارنة
\n\nلنقم باختبار أداء بسيط. سنقارن ثلاث طرق للحصول على الوقت الحالي في حلقة من 100,000 تكرار:
\n\n<?php\n$iterations = 100000;\n\n// الطريقة 1: date()\n$start = microtime(true);\nfor ($i = 0; $i < $iterations; $i++) {\n $now = date('Y-m-d H:i:s');\n}\n$time1 = microtime(true) - $start;\n\n// الطريقة 2: DateTime\n$start = microtime(true);\nfor ($i = 0; $i < $iterations; $i++) {\n $now = new DateTime();\n $now->format('Y-m-d H:i:s');\n}\n$time2 = microtime(true) - $start;\n\n// الطريقة 3: DateTimeImmutable\n$start = microtime(true);\nfor ($i = 0; $i < $iterations; $i++) {\n $now = new DateTimeImmutable();\n $now->format('Y-m-d H:i:s');\n}\n$time3 = microtime(true) - $start;\n\necho \"date(): $time1 ثانية\\n\";\necho \"DateTime: $time2 ثانية\\n\";\necho \"DateTimeImmutable: $time3 ثانية\\n\";\n?>\n\nالنتيجة المتوقعة: date() سيكون الأسرع، يليه DateTime، ثم DateTimeImmutable. الفرق قد يصل إلى 20% في التطبيقات ذات الضغط العالي.
\n\n
4. نصائح إضافية للمحترفين
\n\n- \n
- التخزين المؤقت للوقت: إذا كنت تحتاج إلى نفس الوقت في عدة أماكن، احسبه مرة واحدة في بداية النص البرمجي وخزّنه في متغير. \n
- التعامل مع المناطق الزمنية: استخدم
DateTimeZoneلتوحيد الوقت عبر التطبيق، خاصة إذا كان المستخدمون في مناطق مختلفة. \n - تجنب NOW() في الحلقات: بدلاً من استدعاء
NOW()في كل إدراج، احسب الوقت في PHP وأضفه كقيمة ثابتة. \n
باستخدام هذه التقنيات، ستتمكن من تحسين أداء تطبيقات PHP بشكل ملحوظ وتقليل الاعتماد على قاعدة البيانات.