تقسيم المشروع في PHP: include و require
موقعك فيه عشر صفحات، وكلها تبدأ بالقائمة العلوية نفسها وتنتهي بالتذييل نفسه. ماذا لو أردت إضافة رابط جديد في القائمة؟ هل تعدّل عشرة ملفات؟ في هذا الدرس، وهو الأخير في الكورس، ستتعلم كيف تكتب كل جزء مرة واحدة في ملف مستقل، ثم تضمّنه حيث تحتاجه بـ include و require.
الفكرة: ملفات مثل قطع المكعبات
Section titled “الفكرة: ملفات مثل قطع المكعبات”تضمين ملف يعني: «يا PHP، ضعي محتوى ذلك الملف هنا، كأنني كتبته في هذا المكان». تخيّل مكعبات البناء: تصنع قطعة للترويسة وقطعة للتذييل، ثم تركّبهما في كل صفحة. وإذا عدّلت القطعة، تغيّرت في كل مكان رُكّبت فيه.
لنبدأ بقطعة الترويسة:
<!DOCTYPE html><html lang="ar" dir="rtl"><head> <meta charset="UTF-8"> <title><?= htmlspecialchars($pageTitle) ?> | متجري</title></head><body><nav> <a href="index.php">الرئيسية</a> <a href="about.php">من نحن</a></nav>ثم قطعة التذييل:
<footer> <p>كل الحقوق محفوظة - متجري</p></footer></body></html>والآن أي صفحة في الموقع تصبح قصيرة جداً:
<?php$pageTitle = "الرئيسية";require "header.php";?><h1>أهلاً بك في متجري</h1><p>أحدث المنتجات تجدها هنا.</p><?php require "footer.php"; ?>وهذا ما يصل إلى المتصفح:
<!DOCTYPE html><html lang="ar" dir="rtl"><head> <meta charset="UTF-8"> <title>الرئيسية | متجري</title></head><body><nav> <a href="index.php">الرئيسية</a> <a href="about.php">من نحن</a></nav><h1>أهلاً بك في متجري</h1><p>أحدث المنتجات تجدها هنا.</p><footer> <p>كل الحقوق محفوظة - متجري</p></footer></body></html>لاحظ شيئاً مهماً: المتغير $pageTitle عرّفناه في index.php قبل التضمين، فاستطاع header.php أن يستخدمه. الملف المضمَّن يرى كل المتغيرات الموجودة في مكان تضمينه، كأنه جزء من الملف نفسه.
include أم require؟
Section titled “include أم require؟”الاثنتان تضمّنان الملف، والفرق في ما يحدث إذا لم يوجد الملف:
includeتعرض تحذيراً، وتكمل تنفيذ الصفحة.requireتوقف الصفحة فوراً بخطأ قاتل.
<?phpinclude "missing.php";echo "أكملت بعد include\n";
require "missing.php";echo "هذا السطر لن يظهر\n";عند التشغيل ستظهر رسالة Warning: include(missing.php): Failed to open stream: No such file or directory، ثم الجملة «أكملت بعد include»، ثم يتوقف كل شيء عند require بالرسالة Fatal error: Uncaught Error: Failed opening required 'missing.php'.
أيهما تختار؟ اسأل نفسك: هل تعمل الصفحة بدون هذا الملف؟ ملف الدوال أو الاتصال بقاعدة البيانات ضروري، وإكمال الصفحة بدونه يسبب أخطاء أغرب، فاستخدم require. وهذا حال أغلب الملفات، ولذلك require هي الاختيار الأشهر.
ملف الدوال و require_once
Section titled “ملف الدوال و require_once”الدوال التي تحتاجها في أكثر من صفحة تجمعها في ملف واحد:
<?phpfunction formatPrice(float $price): string { return number_format($price, 2) . " جنيه";}
function discount(float $price, int $percent): float { return $price - $price * $percent / 100;}ثم تضمّنه حيث تحتاجه:
<?phprequire_once "functions.php";require_once "functions.php";
$products = ["قلم" => 5, "حقيبة" => 149.5];
foreach ($products as $name => $price) { echo $name . ": " . formatPrice($price) . "\n";}echo "بعد الخصم: " . formatPrice(discount(200, 15)) . "\n";قلم: 5.00 جنيهحقيبة: 149.50 جنيهبعد الخصم: 170.00 جنيهكتبنا سطر التضمين مرتين عمداً، ولم يحدث شيء! الكلمة _once تعني «مرة واحدة فقط»: إذا كان الملف قد ضُمّن من قبل، تتجاهل PHP الطلب الثاني. جرّب تغيير السطرين إلى require العادية، وستتوقف الصفحة بالخطأ Cannot redeclare، لأن الدالة عُرّفت مرتين.
هذا يحدث كثيراً في المشاريع الكبيرة دون قصد: ملف يضمّن الدوال، ويضمّن ملفاً آخر يضمّنها أيضاً.
| الصيغة | الملف غير موجود | التضمين المكرر |
|---|---|---|
include |
تحذير وتكمل | يُضمَّن مرة أخرى |
require |
خطأ يوقف الصفحة | يُضمَّن مرة أخرى |
include_once |
تحذير وتكمل | يُتجاهل |
require_once |
خطأ يوقف الصفحة | يُتجاهل |
القاعدة العملية: require_once لملفات الدوال والكلاسات والإعدادات، و require لقطع HTML مثل الترويسة والتذييل.
ملف الإعدادات
Section titled “ملف الإعدادات”الملف المضمَّن يستطيع أن يعيد قيمة بـ return، وتستقبلها أنت في متغير. هذه طريقة أنيقة لملفات الإعدادات:
<?phpreturn [ "site_name" => "متجري", "items_per_page" => 12,];<?php$config = require "config.php";
echo $config["site_name"] . "\n";echo $config["items_per_page"] . "\n";متجري12هكذا تجتمع كل إعدادات الموقع في مكان واحد، وهو الأسلوب نفسه الذي يتبعه Laravel في مجلد config.
المسارات و __DIR__
Section titled “المسارات و __DIR__”عندما يكبر المشروع ستضع الملفات في مجلدات:
my-shop/├─ index.php├─ about.php├─ config.php└─ includes/ ├─ header.php ├─ footer.php └─ functions.phpوهنا يظهر فخ: المسار النسبي مثل "includes/header.php" يُحسب من الملف الذي بدأ منه الطلب، لا من الملف الذي كُتب فيه السطر. فإذا ضمّن ملف داخل includes ملفاً آخر، فقد لا يجده.
الحل هو الثابت __DIR__، وقيمته دائماً المسار الكامل لمجلد الملف الحالي:
<?phprequire __DIR__ . "/includes/header.php";بهذه الصيغة يعمل التضمين مهما كان الملف الذي بدأ منه الطلب. استخدمها دائماً في المشاريع الحقيقية.
جرّب بنفسك
Section titled “جرّب بنفسك”ابنِ موقعاً صغيراً من ثلاث صفحات: index.php و about.php و contact.php، تشترك كلها في header.php و footer.php. أضف في الترويسة قائمة تنقل، واجعل كل صفحة تحدد عنوانها في $pageTitle. ثم أضف رابطاً رابعاً في القائمة، وتأكد أنه ظهر في الصفحات الثلاث بتعديل ملف واحد.
تحدٍّ إضافي: ميّز رابط الصفحة الحالية في القائمة بلون مختلف، بمقارنة $pageTitle داخل header.php.
أخطاء شائعة
Section titled “أخطاء شائعة”- تضمين ملف الدوال بـ
requireأكثر من مرة: يسببCannot redeclare. استخدمrequire_once. - استخدام متغير قبل تعريفه: إذا ضمّنت
header.phpقبل تعريف$pageTitleفسترى تحذيرUndefined variable. عرّف المتغيرات أولاً. - الاعتماد على المسارات النسبية في المجلدات الفرعية: استخدم
__DIR__. - مسافة أو سطر فارغ بعد
?>في ملف مضمَّن: يُرسل إلى المتصفح كمخرجات، ويمنعheaderوsession_start. الأفضل ألا تكتب?>في آخر ملفات PHP الخالصة.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
ما الفرق بين include و require عند غياب الملف؟
require تعني أن الملف ضروري، فغيابه خطأ قاتل. أما include فتكتفي بتحذير.
سؤال
ماذا يعطي الثابت __DIR__؟
__DIR__ هو مجلد الملف الذي كُتب فيه، ولذلك يجعل مسارات التضمين ثابتة وموثوقة.
الخلاصة
Section titled “الخلاصة”- التضمين يضع محتوى ملف في مكان السطر، فتكتب الأجزاء المشتركة مرة واحدة.
requireللملفات الضرورية، وincludeلما يمكن الاستغناء عنه.require_onceتمنع تضمين الملف مرتين، وهي الأنسب لملفات الدوال.- الملف المضمَّن قد يعيد قيمة بـ
return، مثل ملف الإعدادات. - استخدم
__DIR__لبناء المسارات، ولا تضمّن ملفاً يحدده الزائر.
مبروك! أنهيت كورس PHP كاملاً. الخطوة التالية: كورس Laravel لبناء تطبيقات ويب احترافية بسرعة.