Elvis vs Null Coalescing: أين يكمن الفرق؟ (تحليل معمق في PHP)
\n\nمرحبًا يا زميل! إذا كنت قد كتبت أي كود بلغة PHP، فبالتأكيد واجهت موقفًا تحتاج فيه إلى التحقق من وجود متغير، واستخدام قيمته إذا كان موجودًا، أو تعيين قيمة افتراضية إذا لم يكن. تبدو مهمة بسيطة، لكنها بالضبط النقطة التي يتعثر فيها المبتدئون (وحتى المحترفون) بين عاملين متشابهين جدًا ولكن مختلفين جوهريًا: short-ternary (Elvis operator) ?: و null coalescing operator ??.
هذا واحد من أكثر الأسئلة شيوعًا على Stack Overflow (آلاف المشاهدات والتصويتات). وليس من دون سبب: الفرق بينهما ليس مجرد فضول أكاديمي. اختيار العامل الخاطئ قد يؤدي إلى أخطاء ستقضي ساعات في تتبعها. دعنا نفهم نهائيًا ما يحدث "تحت الغطاء" ومتى نستخدم كلًا منهما.
\n\nمقدمة سريعة: لماذا نحتاج هذه العوامل؟
\n\nتخيل أنك تكتب كودًا لعرض اسم المستخدم. إذا لم يكن هناك اسم، نعرض "ضيف". الطريقة التقليدية هي استخدام if:
if (isset($userName)) {\n $displayName = $userName;\n} else {\n $displayName = 'ضيف';\n}\n\nهذا يعمل، لكنه طويل. تقدم PHP اختصارات أنيقة. وهنا نصل إلى المعضلة الرئيسية: ?: أم ??؟ للوهلة الأولى، يبدوان متطابقين. لكن هذا فقط للوهلة الأولى.
1. عامل Elvis (?:) — "ملك القيم المنطقية"
\n\nعامل Elvis (سُمي بهذا الاسم لتشابهه مع تسريحة شعر ملك الروك أند رول: ?: — عينان وأنف وخصلة شعر) ظهر في PHP منذ الإصدار 5.3. وهو صيغة مختصرة للعامل الثلاثي (ternary operator).
الصيغة:
\n$result = $expression ?: $default;\n\nماذا يعني هذا؟ ينظر المفسر إلى $expression. إذا كان يتحول إلى true (أي ليس قيمة "خاطئة")، يتم إرجاع $expression. إذا كان $expression قيمة "خاطئة" (false، 0، سلسلة فارغة، null، مصفوفة فارغة، إلخ)، يتم إرجاع $default.
نقطة مهمة: عامل Elvis لا يتحقق من وجود المتغير. إنه يتحقق من صحته المنطقية. إذا كان المتغير غير معرّف، ستحصل على Notice: Undefined index/variable.
\n\nمثال مع مفاجأة:
\n$count = 0;\n$result = $count ?: 10;\necho $result; // سيطبع 10، وليس 0!\n\nلماذا؟ لأن 0 قيمة "خاطئة" (falsy). اعتبر Elvis أن المتغير "فارغ" وأعطى القيمة البديلة. هذا يفاجئ الكثيرين.
2. عامل Null Coalescing (??) — "المنقذ من أخطاء Notice"
\n\nعامل null coalescing ظهر في PHP 7.0 ولقي ترحيبًا حارًا. قوته الخارقة الرئيسية هي أنه يتعامل بأمان مع المتغيرات غير الموجودة دون التسبب في أخطاء.
\n\nالصيغة:
\n$result = $expression ?? $default;\n\nماذا يعني هذا؟ يتحقق العامل من وجود $expression و أنه لا يساوي null. إذا كان الأمر كذلك، يُرجع $expression. وإلا، يُرجع $default.
الفرق الجوهري: ?? يتجاهل جميع القيم "الخاطئة" باستثناء null وعدم التعريف (undefined). 0، ""، false — كل هذه تعتبر قيمًا صالحة وسيتم إرجاعها.
مثال:
\n$count = 0;\n$result = $count ?? 10;\necho $result; // سيطبع 0! لأن المتغير موجود وليس null.\n\nأترى الفرق؟ هذه هي الآلية الرئيسية "تحت الغطاء".
\n\n3. مقارنة "تحت الغطاء": جدول الحقيقة
\n\nدعنا نلخص كل شيء في جدول توضيحي لتثبيت المعلومة. لنفترض أن لدي