كيفية إصلاح "Headers already sent" في PHP: دليل كامل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: "لقد أرسلت شيئًا إلى الشاشة بالفعل، ولا أستطيع فعل ذلك"

\n

إذا سبق لك أن رأيت على موقعك بدلاً من صفحة جميلة شاشة بيضاء مع رسالة مخيفة Warning: Cannot modify header information - headers already sent — فأنت لست وحدك. هذا هو بلا شك أحد أكثر الأخطاء شيوعًا بين مطوري PHP المبتدئين (وليس فقط المبتدئين). على Stack Overflow، حصل هذا السؤال على مئات الآلاف من المشاهدات، وعدد نسخ الكود الخاطئ في العالم يُقاس بالتيرابايت.

\n

لكن الخبر السار هو أن خطأ "Headers already sent" ليس لعنة، بل مجرد تذكير صارم من PHP: "مرحبًا، لقد بدأت بالفعل في إرسال كود HTML، والآن تحاول تغيير رؤوس HTTP. هذا غير مسموح!".

\n

في هذه المقالة، سنشرح لماذا يحدث خطأ headers already sent في PHP، وكيفية العثور عليه، والأهم من ذلك، كيفية إصلاحه نهائيًا. هيا بنا!

\n\n

1. ما هي رؤوس HTTP ولماذا "تم إرسالها بالفعل"؟

\n

قبل الخوض في الكود، دعنا نفهم ببساطة ما يحدث "تحت الغطاء". عندما يتم تنفيذ سكريبت PHP، فإنه يرسل أولاً رؤوس HTTP (header) إلى المتصفح. تحتوي هذه الرؤوس على معلومات خدمية: نوع المحتوى (Content-Type)، الكوكيز (Set-Cookie)، إعادة التوجيه (Location)، حالة الاستجابة (200، 404، 301) وهكذا.

\n

وفقط بعد كل الرؤوس يبدأ إرسال نص المستند — وهو HTML الذي تراه على الصفحة. يسمح PHP بتعديل الرؤوس فقط قبل لحظة إرسال أول بايت من المحتوى.

\n

بمجرد أن تقوم بإخراج شيء ما على الشاشة (عبر echo، print، var_dump أو حتى مجرد مسافة قبل <?php)، يعتبر PHP أن الرؤوس قد أُرسلت بالفعل. أي محاولة لاستدعاء header()، setcookie() أو session_start() بعد ذلك تؤدي إلى خطأ فادح.

\n\n

1.1. مثال كلاسيكي على الخطأ

\n
<?php\necho "مرحبًا بالعالم!";\n// عذرًا! لقد أخرجنا شيئًا بالفعل.\nheader("Location: https://example.com");\n// Warning: Cannot modify header information - headers already sent\n?>
\n

في هذا المثال، يقوم echo بإرسال نص إلى نص المستند. بعد ذلك، لا يستطيع PHP إعادة كتابة الرؤوس لإجراء إعادة التوجيه. هذا منطقي.

\n\n

2. أهم 5 أسباب لحدوث "Headers already sent"

\n

قد لا يكون الخطأ ناتجًا فقط عن echo صريح. إليك السيناريوهات الأكثر شيوعًا التي تقع فيها حتى المطورين ذوي الخبرة:

\n
    \n
  • مسافة أو سطر فارغ قبل <?php — "الخلل" الأكثر شيوعًا. إذا كان هناك مسافة واحدة على الأقل في الملف قبل علامة الفتح، فسيتم إرسالها كمخرجات.
  • \n
  • أحرف BOM غير المرئية (Byte Order Mark) — تم حفظ الملف بترميز UTF-8 with BOM. تعتبر أول 3 بايتات (EF BB BF) مخرجات.
  • \n
  • مخرجات من الملفات المضمنة — في ملف config.php توجد مسافة زائدة بعد ?>.
  • \n
  • الأخطاء والتحذيرات — إذا قام PHP بعرض تحذير (على سبيل المثال، عن استخدام متغير غير معرف)، فهذا يعتبر أيضًا إرسال محتوى.
  • \n
  • دوال print، printf، var_dump قبل header() — أي دالة إخراج تفسد الرؤوس.
  • \n
\n\n

3. كيفية العثور على مصدر المشكلة: 3 طرق

\n

قبل الإصلاح، تحتاج إلى العثور على مصدر "الإخراج الزائد". استخدم إحدى هذه الطرق.

\n\n

3.1. تفعيل عرض جميع الأخطاء

\n

أضف في بداية السكريبت (قبل أي إخراج):

\n
<?php\nerror_reporting(E_ALL);\nini_set('display_errors', 1);\n?>
\n

غالبًا ما يعرض PHP السطر الدقيق الذي حدث فيه الإخراج. ابحث عن رسالة مثل Output started at /path/to/file.php:12.

\n\n

3.2. استخدام الدالة error_get_last()

\n

يمكنك اعتراض آخر خطأ

المدونات

توصيات الكتب