إصلاح خطأ "Headers already sent" في PHP: دليل خطوة بخطوة

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

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

ابدأ الدورة

تعرف على خطأ "Headers already sent": عدوك الجديد (وصديقك)

\n\n

إذا سبق لك البرمجة بلغة PHP، فبالتأكيد واجهت هذا الخطأ. يظهر فجأة، غالباً في أكثر الأوقات غير المناسبة - عندما تكون على وشك إنهاء السكربت. الرسالة مخيفة، حمراء اللون، وتجعلك تعتقد أن الكود بأكمله معطل. لكن في الحقيقة، هذا واحد من أكثر الأخطاء فائدة في PHP. إنه يعلمك كيفية التعامل الصحيح مع بروتوكول HTTP.

\n\n

في هذا الدليل التعليمي، سنشرح لماذا يظهر خطأ Headers already sent، وكيفية تشخيصه، والأهم من ذلك، كيفية إصلاحه بشكل نهائي. لن نكتفي بنسخ إجابة من Stack Overflow - بل سنفهم الجوهر. هيا بنا!

\n\n

ما هي رؤوس HTTP ولماذا يعترض PHP عليها؟

\n\n

قبل العلاج، يجب فهم التشريح. عندما يرسل PHP الرد إلى المتصفح، يفعل ذلك على مرحلتين:

\n\n
    \n
  • أولاً - الرؤوس (headers). هذه معلومات خدمية: نوع المحتوى (Content-Type)، الترميز، الكوكيز، حالة الرد (200 OK، 404 Not Found).
  • \n
  • ثانياً - نص الرد (body). هذا هو HTML نفسه، النص، JSON - ما يراه المستخدم.
  • \n
\n\n

المشكلة أن PHP لا يستطيع إرسال الرؤوس بعد أن بدأ في إرسال النص. إذا حاولت استدعاء header() بعد أن قمت بإخراج أي حرف (حتى مسافة)، سيظهر خطأ PHP:

\n\n
Warning: Cannot modify header information - headers already sent by (output started at /path/to/file.php:12)
\n\n

هذا هو كل السحر. الخطأ ليس قاتلاً - إنه مجرد تحذير بأن دالة header() لم تعمل. لكن العواقب قد تكون خطيرة: لن يتم تنفيذ إعادة التوجيه، لن يتم تعيين الكوكيز، سيتعطل رد JSON.

\n\n

أهم 5 أسباب لحدوث هذا الخطأ

\n\n

دعنا نستعرض السيناريوهات الأكثر شيوعاً. هل تجد نفسك في أحدها؟

\n\n

1. مسافة أو سطر فارغ قبل <?php

\n\n

هذا كلاسيكي. تفتح الملف، وقبل علامة الفتح <?php توجد مسافة، سطر فارغ، أو حرف BOM (Byte Order Mark). يعتبر PHP هذا الحرف جزءاً من الإخراج - وتبدأ المشكلة.

\n\n
// ❌ خطأ: مسافة قبل <?php\n <?php\nheader('Location: /new-page.php');\n?>
\n\n
// ✅ صحيح: لا توجد أحرف قبل <?php\n<?php\nheader('Location: /new-page.php');\n?>
\n\n

2. الإخراج عبر echo أو print قبل دالة header()

\n\n

خطأ منطقي وشائع بين المبتدئين: إخراج شيء أولاً، ثم محاولة إعادة توجيه المستخدم.

\n\n
<?php\necho "مرحباً بالعالم!";\nheader('Location: /thanks.php'); // ❌ خطأ: تم الإخراج بالفعل\n?>
\n\n

3. كود HTML قبل كتلة PHP

\n\n

قد يحتوي الملف على كود مختلط: ترميز HTML أولاً، ثم منطق PHP مع دالة header().

\n\n
<!DOCTYPE html>\n<html>\n<head>\n    <title>موقعي</title>\n</head>\n<body>\n<?php\nheader('Location: /login.php'); // ❌ خطأ: تم إرسال HTML بالفعل\n?>\n</body>\n</html>
\n\n

4. أخطاء PHP ودوال مثل var_dump()

\n\n

قد يقوم السكربت بإخراج تحذيرات أو معلومات تصحيح قبل استدعاء دالة header(). مثلاً، إذا كان display_errors مفعّلاً وقام PHP بإخراج warning.

\n\n
<?php\nvar_dump($some_variable); // إخراج بيانات\nheader('Content-Type: application/json'); // ❌ خطأ\n?>
\n\n

5. أحرف غير مرئية في الملفات المضمنة (include/require)

\n\n

تقوم بتضمين ملف باستخدام include أو require، وفي نهاية هذا الملف يوجد سطر فارغ إضافي أو مسافة بعد علامة الإغلاق ?>.

\n\n
// config.php\n<?php\n$db_host = 'localhost';\n?>\n // ← هذه المسافة بعد ?> تفسد كل شيء!
\n\n

كيف تجد مصدر المشكلة: تشخيص خطوة بخطوة

\n\n

الأهم من ذلك - الخطأ يشير دائماً إلى أين بدأ الإخراج بالضبط. اقرأ الرسالة بعناية

المدونات

توصيات الكتب