define() vs const في PHP: معركة العمالقة في تعريف الثوابت
\n\nهل تساءلت يومًا لماذا يوجد في PHP طريقتان مختلفتان لتعريف الثابت؟ قد يبدو الأمر مكررًا، لكن الفرق بينهما قد يغير بنية كودك بالكامل. هذا السؤال حصد آلاف المشاهدات على Stack Overflow، وليس من دون سبب — فالاختيار بين define() و const يؤثر بشكل كبير على أداء وتصميم تطبيقاتك.
اليوم سنحسم الأمر نهائيًا. ستتعرف ليس فقط على الفروقات التركيبية، بل أيضًا على متى يمنحك كل خيار أفضلية حقيقية. هيا بنا!
\n\nنظرة سريعة: ما هو الثابت في PHP؟
\n\nالثابت (Constant) هو معرف لقيمة ثابتة لا تتغير أثناء تنفيذ السكربت (على عكس المتغيرات). افتراضيًا، الثوابت حساسة لحالة الأحرف، لكن يمكنك تغيير ذلك (مع define()).
مثال على ثابت تقليدي:
\n\n<?php\ndefine("MAX_UPLOAD_SIZE", 10485760); // 10 ميجابايت بالبايت\necho MAX_UPLOAD_SIZE; // 10485760\n?>\n\nنفس المثال مع const:
<?php\nconst MAX_UPLOAD_SIZE = 10485760;\necho MAX_UPLOAD_SIZE;\n?>\n\nيبدو متطابقًا، لكن دعنا نتعمق أكثر.
\n\nالفروقات الرئيسية بين define() و const
\n\nلنوضح الأمور بشكل كامل. إليك الفروقات الأساسية التي يجب أن يعرفها كل مطور PHP.
\n\n1. وقت التعريف: التجميع (Compilation) مقابل التنفيذ (Runtime)
\n\nهذا هو الفرق الجوهري.
\n\n- \n
const— يُعرّف في مرحلة التجميع. هذا يعني أنه لا يمكنك استخدامconstداخل الحلقات أو الشروط أو الدوال. يجب تعريفه في "جسم" الكلاس (لثوابت الكلاسات) أو في النطاق العام. \n define()— يُنفّذ في وقت التشغيل. يمكنك وضعه في أي مكان: داخلifأوforأوwhileأو حتى داخل دالة (رغم أنها ممارسة سيئة). \n
مثال لن يعمل مع const:
<?php\nif (PHP_OS === 'WINNT') {\n const PLATFORM = 'Windows';\n // خطأ فادح: لا يمكن استخدام const داخل هيكل تحكم\n}\n?>\n\nأما مع define() فالأمر سهل:
<?php\nif (PHP_OS === 'WINNT') {\n define('PLATFORM', 'Windows');\n echo PLATFORM; // Windows\n}\n?>\n\n2. أنواع البيانات: المصفوفات والكائنات
\n\nلفترة طويلة، كان define() يدعم فقط الأنواع العددية (النصوص، الأرقام، القيم المنطقية). منذ PHP 7، أصبح define() يدعم المصفوفات.
const يدعم المصفوفات أيضًا (منذ PHP 5.6)، لكنه لا يدعم الكائنات أو التعبيرات:
<?php\n// يعمل مع PHP 7+\ndefine('FRUITS', ['تفاح', 'موز', 'كرز']);\necho FRUITS[1]; // موز\n\n// يعمل أيضًا (PHP 5.6+)\nconst COLORS = ['أحمر', 'أخضر', 'أزرق'];\n\n// لكن هذا سيؤدي لخطأ!\n// const RESULT = 2 + 3; // يعمل، هذا تعبير ثابت\n// const DYNAMIC = rand(1, 10); // خطأ! ليس تعبيرًا ثابتًا\n?>\n\nملاحظة مهمة: define() يمكنه استخدام نتائج الدوال (define('SITE_NAME', get_site_name()))، بينما const يقبل فقط التعبيرات الثابتة (أرقام، نصوص، ثوابت أخرى).
3. مساحة الأسماء (Namespace) ونطاق الرؤية
\n\nهناك فارق دقيق لكنه مهم.
\n\n- \n
define()— يُنشئ دائمًا ثابتًا عامًا. حتى لو استخدمته داخل مساحة اسم، سيظل الثابت متاحًا من أي مكان. \n const— يخضع لقواعد مساحة الأسماء. الثابت المُعرّف في namespaceMyApp\\ConfigسيُسمىMyApp\\Config\\SITE_NAME. \n
مثال توضيحي:
\n\n<?php\nnamespace MyApp\\Config;\n\n// هذا سيُعرّف الثابت في النطاق العام\n// define('DB_HOST', 'localhost');\n\n// هذا سيُعرّف الثابت داخل مساحة الاسم MyApp\\Config\nconst DB_HOST = 'localhost';\n\necho DB_HOST; // localhost\necho \\MyApp\\Config\\DB_HOST; // localhost (الوصول الكامل)\n?>\n\nمتى تستخدم define() ومتى تستخدم const؟
\n\nإليك دليل سريع لاتخاذ القرار الصحيح:
\n\n- \n
- استخدم
constعندما:\n- \n
- تحتاج ثوابت خاصة بكلاس (class constants). \n
- تريد ثوابت ضمن مساحة اسم محددة. \n
- تريد أداءً أفضل (const أسرع قليلاً). \n
- تعمل مع قيم ثابتة لا تتغير. \n
\n - استخدم
define()عندما:\n- \n
- تحتاج تعريف ثابت بناءً على شرط (مثل if). \n
- تريد استخدام تعبيرات ديناميكية (مثل نتائج دوال). \n
- تحتاج ثوابت عامة متاحة من أي مكان. \n
- تعمل مع مصفوفات كبيرة أو بيانات معقدة. \n
\n
الخلاصة: أيهما أفضل؟
\n\nلا توجد إجابة واحدة تناسب الجميع. const مثالي للثوابت الثابتة داخل الكلاسات ومساحات الأسماء، بينما define() يوفر مرونة أكبر للثوابت العامة والديناميكية. القاعدة الذهبية: استخدم const افتراضيًا، وانتقل إلى define() فقط عندما تحتاج مرونته.
هل لديك تجربة مع أحد هذين الأسلوبين؟ شاركنا في التعليقات!