Introduction : "Vous avez déjà envoyé quelque chose à l'écran, et je ne peux pas"
\nSi vous avez déjà vu sur votre site un écran blanc avec un message effrayant Warning: Cannot modify header information - headers already sent à la place d'une belle page — vous n'êtes pas seul. C'est sans doute l'une des erreurs les plus courantes chez les développeurs PHP débutants (et même expérimentés). Sur Stack Overflow, cette question a été vue des centaines de milliers de fois, et le nombre de copies de code incorrect dans le monde se mesure en téraoctets.
Mais la bonne nouvelle, c'est que l'erreur « Headers already sent » n'est pas une malédiction, mais simplement un rappel strict de PHP : « Hé, tu as déjà commencé à envoyer du code HTML, et maintenant tu essaies de modifier les en-têtes HTTP. Ce n'est pas permis ! ».
\nDans cet article, nous allons voir pourquoi l'erreur headers already sent se produit en PHP, comment la trouver et, surtout, comment la corriger une fois pour toutes. C'est parti !
\n\n1. Que sont les en-têtes HTTP et pourquoi sont-ils "déjà envoyés" ?
\nAvant de plonger dans le code, comprenons simplement ce qui se passe « sous le capot ». Lorsqu'un script PHP s'exécute, il envoie d'abord les en-têtes HTTP au navigateur. Ceux-ci contiennent des informations de service : le type de contenu (Content-Type), les cookies (Set-Cookie), les redirections (Location), le statut de la réponse (200, 404, 301), etc.
Et ce n'est qu'après tous les en-têtes que commence l'envoi du corps du document — le HTML que vous voyez sur la page. PHP permet de modifier les en-têtes uniquement avant que le premier octet du contenu ne soit envoyé.
\nDès que vous affichez quelque chose à l'écran (via echo, print, var_dump ou même un simple espace avant <?php), PHP considère que les en-têtes sont déjà envoyés. Toute tentative d'appeler header(), setcookie() ou session_start() après cela entraîne une erreur fatale.
1.1. Exemple classique d'erreur
\n<?php\necho "Bonjour le monde !";\n// Oups ! Nous avons déjà affiché quelque chose.\nheader("Location: https://example.com");\n// Warning: Cannot modify header information - headers already sent\n?>\nDans cet exemple, echo envoie du texte dans le corps du document. Après cela, PHP ne peut pas réécrire les en-têtes pour effectuer une redirection. Logique.
2. Top 5 des causes de l'erreur "Headers already sent"
\nL'erreur peut être causée non seulement par un echo explicite. Voici les scénarios les plus fréquents qui piègent même les développeurs expérimentés :
- \n
- Espace ou ligne vide avant
<?php— le "bug" le plus courant. Si le fichier contient ne serait-ce qu'un espace avant la balise d'ouverture, il sera envoyé dans la sortie. \n - Caractères invisibles BOM (Byte Order Mark) — le fichier est enregistré en UTF-8 with BOM. Les 3 premiers octets (EF BB BF) sont considérés comme une sortie. \n
- Sortie des fichiers inclus — le fichier
config.phpcontient un espace supplémentaire après?>. \n - Erreurs et avertissements — si PHP affiche un avertissement (par exemple, concernant l'utilisation d'une variable non définie), cela est également considéré comme un envoi de contenu. \n
- Fonctions
print,printf,var_dumpavant header() — toute fonction d'affichage casse les en-têtes. \n
3. Comment trouver la source du problème : 3 méthodes
\nAvant de corriger, il faut trouver d'où vient la sortie « superflue ». Utilisez l'une de ces méthodes.
\n\n3.1. Activer l'affichage de toutes les erreurs
\nAjoutez au début du script (avant toute sortie) :
\n<?php\nerror_reporting(E_ALL);\nini_set('display_errors', 1);\n?>\nPHP affiche souvent la ligne exacte où la sortie a eu lieu. Cherchez un message comme Output started at /path/to/file.php:12.
3.2. Utiliser la fonction error_get_last()
\nVous pouvez intercepter la dernière erreur