Résoudre l’erreur PHP Cannot modify header information – headers already sent

Illustration representing PHP web server debugging and configuration

Tout administrateur système ou développeur web a déjà rencontré ce message d’erreur explicite mais parfois déroutant : PHP Warning: Cannot modify header information – headers already sent by (output started at …). Ce problème survient principalement lors de l’utilisation de fonctions manipulant les en-têtes HTTP, comme header(), setcookie() ou session_start().

Comprendre le mécanisme du protocole HTTP

Le protocole HTTP impose un ordre strict dans la transmission des réponses : le serveur doit d’abord expédier les en-têtes (headers), qui précisent le code statut, les cookies et le type de contenu, avant d’envoyer le corps du document (le code HTML, le flux JSON ou le texte brut). Dès que le moteur PHP génère le moindre octet de contenu visible, il clôture l’envoi des en-têtes pour entamer le flux de données. Si votre code tente ultérieurement de modifier les en-têtes, l’interpréteur bloque l’action et génère cet avertissement.

Lire correctement le message d’erreur

L’avantage de cet avertissement est qu’il fournit précisément les deux éléments responsables du blocage :

  • Le fichier et la ligne où l’en-tête est appelé : c’est l’emplacement de votre fonction header() ou session_start().
  • Le fichier et la ligne où l’affichage a commencé : c’est la véritable cause du problème, indiquée après la mention output started at.

Les causes fréquentes d’envoi prématuré

1. Espaces et lignes vides parasites

La source la plus commune reste la présence d’espaces invisibles, de sauts de ligne ou de tabulations situés avant la balise ouvrante <?php ou après la balise fermante ?>. Pour éradiquer ce risque sur les scripts purement PHP, la règle d’or consiste à supprimer totalement la balise fermante en fin de fichier. PHP n’en a pas besoin et cela évite d’envoyer un saut de ligne accidentel au client.

2. L’encodage du fichier et le BOM (Byte Order Mark)

Certains éditeurs de texte enregistrent les fichiers en UTF-8 en y injectant une signature invisible appelée BOM en tête de document. Même si votre code semble débuter dès le premier caractère visible, PHP lira ces octets masqués et débutera immédiatement l’envoi du corps HTTP. Veillez toujours à configurer votre éditeur pour sauvegarder en « UTF-8 sans BOM » (UTF-8 without BOM).

3. Inclusions de fichiers et messages d’erreurs

Lorsque vous intégrez des fichiers externes, un espace situé dans une dépendance déclenchera l’émission du corps de réponse. Si vous rencontrez des dysfonctionnements lors de l’appel de fichiers distants ou locaux, pensez à auditer vos inclusions, comme nous l’avions vu dans l’analyse d’une erreur include sur serveur php OVH. De plus, un simple avertissement PHP ou une directive echo non désirée avant un appel de redirection produira exactement la même coupure.

La solution du tampon de sortie (Output Buffering)

Une méthode de contournement répandue consiste à différer l’envoi des flux vers le client via le système de cache de sortie de PHP. En activant ce mécanisme, PHP conserve l’intégralité du contenu produit en mémoire tampon plutôt que de le transmettre immédiatement au serveur web.

Pour l’activer localement dans un script :

  • Placez ob_start(); tout en haut de votre script principal, avant toute exécution de code.
  • Clôturez à la fin avec ob_end_flush(); pour libérer le contenu vers le client.

Bien que pratique pour dépanner rapidement une application existante, l’utilisation du tampon ne doit pas devenir un masque masquant une mauvaise architecture. Il reste préférable d’isoler la logique de routage et de traitement des données avant toute génération d’interface.

Alternative en cas d’impossibilité technique

Si la structure de votre code ne permet plus de modifier les en-têtes HTTP au moment où l’action de redirection doit se produire, vous pouvez déléguer ce saut au navigateur via une redirection en utilisant javascript injectée dans la page, même si cette approche reste moins propre pour le référencement naturel qu’une redirection serveur 301 ou 302 native.

À lire aussi