الثابت اسم لقيمة لا تتغير أبدًا أثناء تشغيل السكربت. عرّفه بـ const MAX_USERS = 100; أو define('MAX_USERS', 100);، ثم استخدم الاسم وحده، دون $.
جرى العرف على كتابة أسماء الثوابت بصيغة UPPER_SNAKE_CASE. وهي عامة: الثابت المعرّف في أعلى الملف مرئي داخل كل دالة دون global.
define() مقابل const
كلاهما ينشئ ثابتًا، لكنهما يعملان في وقتين مختلفين. تُحسم const عندما تترجم PHP الملف، وتعمل define() مثل أي استدعاء دالة آخر.
const | define() | |
|---|---|---|
داخل if والحلقات والدوال | لا | نعم |
| اسم مبني من متغير | لا | نعم |
| ثوابت الأصناف | نعم | لا |
| يمكن أن تكون القيمة تعبيرًا | نعم، من ثوابت وقيم حرفية | نعم، أي قيمة |
| يُضاف إلى نطاق الأسماء تلقائيًا | نعم | لا (اكتب الاسم الكامل) |
استخدم const افتراضيًا، لأنها أقصر ويُتحقق منها وقت الترجمة. واستخدم define() عندما يعتمد الثابت على شرط أو على اسم محسوب.
لا يمكن تغيير الثوابت
الإسناد إلى ثابت خطأ تحليل:
<?php
const LIMIT = 10;
LIMIT = 20;
PHP Parse error: syntax error, unexpected token "=" in /home/index.php on line 3
تعريف الثابت نفسه مرتين ليس خطأً، لكن PHP تطبع تحذيرًا وتحتفظ بالقيمة الأولى:
<?php
define("LIMIT", 10);
define("LIMIT", 20);
echo LIMIT; // 10
Warning: Constant LIMIT already defined in /home/index.php on line 3
عندما تكون القيمة قد عُيّنت مسبقًا على الأرجح (مثلًا في ملف إعدادات يُحمّل أكثر من مرة)، تحقق أولًا بـ defined():
المصفوفات الثابتة
يمكن أن يحمل الثابت مصفوفة. يمكنك قراءتها بـ NAME[key] والمرور عليها وتمريرها، لكن لا يمكنك تعديلها.
ثوابت الأصناف
داخل الصنف، تعرّف const ثابتًا يخص الصنف. اقرأه بـ ClassName::NAME من الخارج وبـ self::NAME أو static::NAME من الداخل. يمكن أن تكون لثوابت الأصناف رؤية (visibility)، ويمكن أن تكون final، ومنذ PHP 8.3 يمكنها التصريح بنوع.
مجموعة ثوابت أصناف مترابطة مثل STATUS_NEW وSTATUS_PAID تُكتب غالبًا بشكل أفضل كـ enum، الذي يمنع أيضًا تمرير قيم غير صالحة.
الثوابت السحرية: LINE و__FILE__ و__DIR__ وغيرها
تتغير قيمة الثوابت السحرية بحسب مكان ظهورها. وتُملأ وقت الترجمة.
أكثرها استخدامًا __DIR__، وهو مجلد الملف الحالي. بناء مسارات التضمين منه يجعلها تعمل أيًا كان المجلد الذي بدأ منه السكربت: require __DIR__ . '/config.php';. راجع include وrequire للنمط الكامل.
ثوابت مدمجة تستحق المعرفة
تعرّف PHP كثيرًا من الثوابت الخاصة بها. وهذه تظهر طوال الوقت:
PHP_EOL هو نهاية السطر في النظام الذي تعمل عليه PHP ("\n" على لينكس وmacOS، و"\r\n" على ويندوز). وهو مخصص للنص المكتوب في الملفات والطرفية، أما في مخرجات HTML فالسطر الجديد لا يظهر، فاستخدم <br> هناك.
الأسئلة الشائعة
ما الفرق بين define() وconst في PHP؟
const بنية لغوية تُحسم عند ترجمة الملف: تعمل في المستوى الأعلى وداخل الأصناف، لكن ليس داخل if أو الحلقات أو الدوال. أما define() فدالة تُستدعى أثناء التشغيل، لذا تعمل في أي مكان ويمكن بناء الاسم من متغير، لكنها لا تستطيع تعريف ثوابت الأصناف.
هل يمكن أن يكون ثابت PHP مصفوفة؟
نعم. كل من const COLORS = ['red', 'green']; وdefine('COLORS', ['red', 'green']); يعمل، وتقرأ عنصرًا بـ COLORS[0]. ولا يمكن تعديل المصفوفة بعد ذلك.
كيف أتحقق مما إذا كان ثابت معرّفًا في PHP؟
استخدم defined('NAME')، التي تأخذ الاسم كنص وتعيد true أو false. ومن الأنماط الشائعة if (!defined('APP_ENV')) { define('APP_ENV', 'production'); }. ولثوابت الأصناف مرّر 'ClassName::NAME'.
ما الثوابت السحرية في PHP؟
ثوابت تعتمد قيمتها على مكان كتابتها: __LINE__ (السطر الحالي)، و__FILE__ (المسار الكامل للملف)، و__DIR__ (مجلده)، و__FUNCTION__ و__CLASS__ و__METHOD__ و__NAMESPACE__. تُكتب بشرطتين سفليتين على كل جانب، وهي غير حساسة لحالة الأحرف.