include في PHP

من موسوعة حسوب
< PHP

(PHP 4, PHP 5, PHP 7)

تعمل عبارة include على تضمين ومعالجة الملف المحدّد.

ينطبق التوثيق التالي على عبارة require.

تُضمّن الملفات بالاعتماد على المسار المعطى للعبارة، وفي حال عدم تحديد المسار، تأخذ include المسار المحدد في include_path. إن لم يكن الملف موجودًا في include_path ستتحقّق include في المجلّد الذي يحتوي على الشيفرة التي أجرت الاستدعاء وفي مجلد العمل الحالي قبل أن تطلق خطأً.

تطلق بنية include تحذيرًا إن لم تتمكن من العثور على الملف، وتختلف في ذلك عن require التي تطلق خطأً مميتًا (fatal error).

إن كان مسار الملف محدّدًا -سواء أكان مطلقًا (أي يبدأ المسار باسم محرك الأقراص أو الرمز \ في ويندوز، أو الرمز / في أنظمة يونكس/لينكس) أو نسبيًا أي في المجلد الحالي (أي يبدأ بالرمز . أو ..)- تتجاهل اللغة قيمة include_path نهائيًا. فعلى سبيل المثال، إن كان اسم الملف يبدأ بالسابقة ‎../‎، فسيبحث مفسر اللغة عن الملف المطلوب في المجلد الأب.

عند تضمين الملف، ترث الشيفرة الموجودة فيه نطاق المتغيرات من السطر الذي تمت فيه عملية التضمين، وتصبح جميع المتغيرات المتوفرة في ذلك السطر ضمن الملف المستدعي متاحةً للملف المستدعى من تلك النقطة فصاعدًا. ولكن، تكون الأصناف والدوال المعرّفة في الملف المضمن ضمن النطاق العام.

المثال 1: مثال بسيط عن include

vars.php

<?php

$color = 'green';
$fruit = 'apple';

?>

test.php
<?php

echo "A $color $fruit"; // A

include 'vars.php';

echo "A $color $fruit"; // A green apple

?>

إن جرى التضمين داخل دالة في الملف المستدعي، فإن الشيفرة الموجودة في الملف المستدعى ستعمل كما لو أنها معرّفة داخل تلك الدالة، وهذا يعني أنّ الشيفرة ستكون ضمن نطاق المتغيرات في تلك الدالة. هناك استثناء لهذه الحالة وهي الثوابت السحرية (magic constants) والتي يعالجها المفسر قبل تضمين الملف.

في المثال التالي يصبح الملف vars.php ضمن نطاق الدالة foo()‎ لذا لن يكون المتغير ‎$fruit متاحًا خارج هذا النطاق.

المثال 2: التضمين داخل الدوال

<?php

function foo()
{
	global $color;

	include 'vars.php';

	echo "A $color $fruit";
}


foo();                	  // A green apple
echo "A $color $fruit";   // A green

?>

عند تضمين ملف معين يخرج المفسّر من وضع PHP ويدخل في وضع HTML في بداية الملف الهدف، ثم يعود إلى وضع PHP في نهايته؛ ولهذا السبب، يجب إحاطة الشيفرة التي يفترض أن تُنفّذ كشيفرة PHP في الملف الهدف بأوسمة بدء ونهاية الشيفرة الخاصة بلغة PHP.

إن كانت "مغلِّفات تضمين URL"‏ ‎(URL include wrappers)‎ مفعّلة في PHP، فيمكن تحديد الملف المراد تضمينه باستخدام عنوان URL (بواسطة HTTP أو أي مغلِّف آخر، راجع البروتوكولات والمغلِّفات المدعومة للاطلاع على قائمة بالبروتوكولات) بدلًا من مسار محلّي. إن فسّر الخادم الهدف الملف الهدف على أنّه شيفرة PHP، فيمكن تمرير المتغيّرات إلى الملف المضمن باستخدام سلسلة طلب URL نصية كتلك المستخدمة في HTTP GET. هذا لا يشبه تضمين الملف وجعله يرث نطاق المتغيرات من الملف الأب، فالشيفرة تعمل في الخادم البعيد وتُضمَّن الشيفرة في الملف المحلي.

يفترض المثال التالي أن العنوان www.example.com مهيّأً لتفسير ملفات ‎.php وليس ملفات ‎txt. والمقصود بكلمة «يعمل» في التعليقات هنا أن المتغيرين ‎$foo و ‎$bar متاحان في الملف المضمَّن.

المثال 3: التضمين بواسطة HTTP

<?php


// لن يعمل، فالملف المستدعى نصّي وليس شيفرة
include 'http://www.example.com/file.txt?foo=1&bar=2';

// لن يعمل، لأن البحث سيكون في الملفات المحلية وليس في الخادم

include 'file.php?foo=1&bar=2';

// سيعمل.
include 'http://www.example.com/file.php?foo=1&bar=2';

$foo = 1;
$bar = 2;
include 'file.txt';  
// سيعمل.
include 'file.php';
// سيعمل.

?>

تحذير أمني

يمكن للملفات البعيدة أن تُعالج في الخادم البعيد (يعتمد ذلك على امتداد الملف وعلى ما إذا كان لدى الخادم البعيدة القدرة على تشغيل ملفات PHP أو لا) ولكن يجب عليه إنتاج شيفرة PHP صالحة لأنّها ستعالج في الخادم المحلي. إن كان المطلوب معالجة ملف الشيفرة في الخادم البعيد وعرض مخرجاته فقط، فإن استخدام الدالة readfile()‎ سيكون أفضل بكثير. فيما عدا ذلك، يجب أخذ أقصى درجات الحيطة والحذر للتأكد من أن الشيفرة البعيدة تنتج شيفرة صالحة للعمل وحسب ما هو مطلوب.

راجع أيضًا دالتي fopen()‎ و file()‎ للمزيد من المعلومات.

معالجة ما ترجعه include

ترجع البنية include القيمة FALSE عند فشلها في استدعاء الملف وتطلق تحذيرًا warning، أما عند نجاحها في أداء عملها فإنّها ترجع القيمة 1 إلا إذا تجاوز الملف المضمّن ذلك. من الممكن تنفيذ عبارة return داخل الملف المضمّن لإنها عملية التنفيذ فيه والعودة إلى الشيفرة التي استدعته. كذلك يمكن إرجاع قيم من الملف المضمَّن. ويمكن الحصول على قيمة استدعاء include كما هو الحال مع الدوال الاعتيادية، ولكن لا يمكن القيام بذلك مع الملفات البعيدة المضمّنة إلا إذا تضمنت مخرجات هذه الملفات أوسمة بدء وانتهاء شيفرة PHP صالحة (كما هو حال أيّ ملفّ محلّي). يمكن التصريح عن المتغيرات المطلوبة ضمن هذه الأوسمة وستُضاف إلى الملف المستدعي في المكان الذي جرت فيه عملية الاستدعاء.

لمّا كانت include بنيةً خاصةً في اللغة، فلا حاجة لاستخدام الأقواس حول المعاملات، ولكن توخّ الحذر عند مقارنة القيمة المرجعة.

المثال 4: مقارنة القيمة المرجعة من include

<?php

// لن تعمل لأنّها ستعالج على أنّها
// include(('vars.php') == TRUE)
// أي بمعنى أنّها
// include('')

if (include('vars.php') == TRUE) {
	echo 'OK';
}

// ستعمل
if ((include 'vars.php') == TRUE) {
	echo 'OK';
}
?>

المثال 5: include وعبارة return

return.php

<?php

$var = 'PHP';

return $var;

?>

noreturn.php
<?php

$var = 'PHP';

?>

testreturns.php

<?php

$foo = include 'return.php';

echo $foo;
// 'PHP' تطبع

$bar = include 'noreturn.php';

echo $bar;
// تطبع 1

?>

يمتلك المتغير ‎$bar القيمة 1 لأنّ عملية التضمين جرت بنجاح. لاحظ الفرق بين الأمثلة السابقة. يستخدم المثال الأول return ضمن الملف المضمَّن في حين لا تستخدم هذه العبارة في الملف الثاني. إن لم يكن بالإمكان تضمين الملف، فسترجع البنية include القيمة FALSE وستطلق خطأً من نوع E_WARNING.

في حال وجود دوالّ معرّفة في الملف المضمَّن، فيمكن استخدامها في الملف الرئيسي وبصورة مستقلّة إن كانت قبل عبارة return أو بعدها. إن ضُمِّن الملف مرتين، فستطلق PHP 5 خطأً قاتلًا (fatal error) لأن التصريح عن الدوال قد تمّ مسبقًا، في حين لا توجد أي مشكلة في PHP 4 تجاه تعريف الدوال بعد عبارة return الموجودة في الملف المُضمّن. يُنصح باستخدام include_once بدلًا من الفحص للتأكد من تضمين الملف والإرجاع بالاعتماد على عبارة شرطية إلى داخل الملف المضمّن.

هناك طريقة أخرى لتضمين ملف PHP إلى متغيّر، وهي بالتقاط المخرجات باستخدام دوال التحكم بالمخرجات مع include. فمثلًا:

المثال 6: استخدام تخزين المخرجات output buffering لتضمين ملف PHP في سلسلة نصية

<?php
$string = get_include_contents('somefile.php');

function get_include_contents($filename) {
	if (is_file($filename)) {
    	ob_start();
    	include $filename;
    	return ob_get_clean();
	}
	return false;
}

?>

لتضمين الملفات تلقائيًا في الشيفرات، راجع أيضًا خياري auto_prepend_file و auto_append_file في ملف الإعدادات php.ini.

ملاحظة: لا يمكن استدعاء include باستخدام دوال المخزنةِ أسماؤها في متغيرات، وذلك لأنّها بنية وليست دالة.

راجع أيضًا require و require_once و include_once و get_included_files()‎ و readfile()‎ و virtual()‎.

مصادر