W3docs

Fonction PHP headers_sent() : Tout ce que vous devez savoir

En tant que développeur PHP, vous pouvez vérifier si les en-têtes HTTP ont déjà été envoyés au client. headers_sent() est une fonction intégrée en PHP.

Chaque réponse HTTP est divisée en deux parties : un bloc d'en-têtes (code de statut, Content-Type, cookies, redirections) suivi du corps de la réponse. Le problème est que les en-têtes doivent être envoyés avant tout contenu du corps. Dès que PHP envoie un seul octet de corps, il expédie les en-têtes et les verrouille — tout appel ultérieur à header(), setcookie(), ou session_start() déclenche alors le célèbre avertissement Cannot modify header information - headers already sent.

headers_sent() est la fonction intégrée qui vous permet de vérifier, avant d'essayer d'envoyer un en-tête, s'il est déjà trop tard. Ce guide couvre sa syntaxe, ses paramètres par référence, ce qui provoque une sortie prématurée et comment y remédier.

Ce que fait headers_sent()

headers_sent() retourne un booléen :

  • true — les en-têtes ont déjà été envoyés (la sortie a commencé). Tout appel ultérieur à header() / setcookie() échouera.
  • false — aucune sortie n'a encore commencé, il est donc encore possible de définir des en-têtes.

Protéger la logique des en-têtes avec headers_sent() vous permet d'éviter l'avertissement et de gérer l'échec gracieusement (par exemple, journaliser le problème ou utiliser une redirection JavaScript) au lieu de faire planter la page.

Syntaxe

headers_sent(string &$filename = null, int &$line = null): bool

Les deux paramètres sont optionnels et passés par référence. Lorsque les en-têtes ont été envoyés, PHP les remplit avec l'emplacement de la sortie qui les a déclenchés :

  • $filename — le nom du fichier source où la sortie a commencé en premier.
  • $line — le numéro de ligne dans ce fichier.

C'est ce qui rend headers_sent() si utile pour le débogage : elle vous pointe directement vers le coupable.

Utilisation de base

Vérifiez la valeur de retour avant d'envoyer un en-tête :

<?php

if (!headers_sent()) {
    header('Location: /dashboard');
    exit;
}

echo 'Headers were already sent, cannot redirect via HTTP.';

Si aucune sortie n'a commencé, l'en-tête de redirection est envoyé. Sinon, le script évite l'avertissement fatal et affiche un message de repli.

Trouver où la sortie a commencé

Passez les deux variables de référence pour savoir exactement ce qui a envoyé les en-têtes — indispensable lorsqu'un espace parasite ou un echo est enfoui dans un fichier inclus :

<?php

if (headers_sent($file, $line)) {
    echo "Headers already sent in $file on line $line";
} else {
    setcookie('theme', 'dark');
    echo 'Cookie set successfully.';
}

Si la condition est vraie, vous obtenez un message comme Headers already sent in /var/www/header.php on line 12, vous indiquant précisément où chercher.

Ce qui déclenche "Headers Already Sent"

Tout ce qui produit une sortie de corps avant votre appel d'en-tête expédie les en-têtes. Causes courantes :

  • Un espace ou une ligne vide avant <?php — même un seul espace ou retour à la ligne compte comme une sortie.
  • Un retour à la ligne après le ?> fermant d'un fichier inclus. (Bonne pratique : omettre entièrement le ?> fermant dans les fichiers PHP purs.)
  • echo, print, printf, ou var_dump exécutés avant l'en-tête.
  • Un fichier UTF-8 enregistré avec un BOM (byte-order mark) — ces octets invisibles en début de fichier constituent une sortie.
  • Des avertissements/notices PHP affichés sur la page (lorsque display_errors est activé) avant les en-têtes.

Résoudre le problème avec la mise en tampon de sortie

Si vous ne pouvez pas réorganiser votre code pour que tous les en-têtes viennent en premier, encapsulez le script dans un tampon de sortie. ob_start() conserve le corps en mémoire au lieu de l'envoyer immédiatement, de sorte que les en-têtes restent modifiables jusqu'à ce que le tampon soit vidé :

<?php

ob_start();              // start buffering — nothing is sent yet

echo 'Some early output';

// Still safe: the echo above is held in the buffer, headers are not sent
setcookie('user', 'jane');
header('X-App-Version: 2.0');

ob_end_flush();          // now send headers, then the buffered body

Comme la sortie est mise en tampon, headers_sent() retournerait toujours false après le echo, et les appels ultérieurs à setcookie() et header() réussissent.

Fonctions associées

  • header() — envoyer un en-tête HTTP brut.
  • headers_list() — lister les en-têtes en attente ou déjà envoyés.
  • setcookie() — définir un cookie (envoie un en-tête Set-Cookie).
  • ob_start() — démarrer la mise en tampon de sortie pour retarder l'envoi des en-têtes.
  • PHP Sessionssession_start() envoie aussi des en-têtes et est un déclencheur fréquent.

Conclusion

headers_sent() est une petite garde mais essentielle : appelez-la avant tout header(), setcookie(), ou session_start() pour vérifier si une sortie a déjà commencé. Lorsqu'elle retourne true, les arguments par référence $filename et $line identifient précisément la sortie en cause pour que vous puissiez la corriger — ou encapsulez votre script dans ob_start() pour garder les en-têtes modifiables jusqu'à ce que vous soyez prêt à vider le tampon.

Pratique

Pratique
Qu'est-ce qui peut provoquer l'avertissement 'headers already sent' en PHP ?
Qu'est-ce qui peut provoquer l'avertissement 'headers already sent' en PHP ?
Was this page helpful?