[PHP] Erreur : Cannot modify header information : headers already sent by

Attention, cet article a été déplacé dans les archives, donc le contenu peut ne plus être à jour. A vous de voir 🙂

L’erreur du jour qui m’a fait frémir : « Warning : Cannot modify header information – headers already sent by  »
Sa cause ? On tente de modifier des entêtes de documents alors que des informations ont déjà été envoyées au client.

Pour avoir passé une demi-heure à chercher des solutions valables, voici le processus à suivre pour résoudre ce problème :

  1. Regarder si aucun echo, espace, ou autre bout de code html n’existe dans le fichier avant toute fonction de modification d’entêtes : (header(), setcookie(), session_start(), et autres)
  2. Dans les fichiers inclus avant l’appel de votre fonction, vérifier qu’aucun espace ne s’est glissé entre des balises PHP.
    Verifier soigneusement le haut de page, avant la premiere balise PHP (<?php), et le bas de page, après la fermeture de la dernière balise PHP.
  3. Il est possible que l’entête X-Powered-By soit envoyée par PHP. Cette entête contenant uniquement la version de PHP utilisée, vous pouvez la désactiver sans crainte : Désactiver X-Powered-By.

Ca ne marche toujours pas ? Toujours une erreur modify header ?
Voici deux solutions, pour deux problèmes différents :

  • Vous n’utilisez que la fonction session_start(), il n’y a rien au dessus.
    Supprimez la fonction session_start();
    Ajoutez cette ligne dans votre fichier .htaccess :
    php_value session.auto_start 1
    Ou ajoutez cette ligne dans votre fichier php.ini :
    session.auto_start 1
    Attention, c’est une méthode qui est déconseillée !
  • Tout a été tenté, rien ne marche ?
    Ajoutez tout en haut du fichier PHP appelé la fonction : ob_start();
    Ajoutez tout en bas du fichier PHP appelé la fonction : ob_end_flush();
    Explication : ob_start va retenir l’envoi de données, et ob_end_flush les liberera 🙂
    Cette « bidouille » permet d’envoyer des cookies en plein milieu d’une page, et d’autres choses pas très nettes 😮 .

J’espère que cet article a pu vous aider à résoudre l’erreur « Cannot modify header information : headers already sent by« .Sinon, je peux toujours vous donner un coup de main dans les commentaires 😉

Edit : une autre solution proposée par le blog Midnight Cafe
Ajoutez cette ligne dans votre fichier .htaccess :
output_buffering on

Edit2 : Dans les commentaires, Gloup évoque le fait que des fichiers en UTF-8 avec BOM peuvent provoquer cette erreur. Il suffit alors de les réencoder en UTF-8 sans BOM !

Partager cet article

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

  • Je le fais dans mes scripts, mais j’ai jugé bon de ne pas alourdir l’article avec une notion supplémentaire 🙂

  • Afin d’éviter les espaces indésirables en fin de fichier tu peux aussi ne pas mettre la balise fermante ?> Pas mal de frameworks font ça afin d’éviter les erreurs.

  • Je crois aussi que ne pas mettre de balise ?> est plus rapide à l’execution… Le php engine detecte une fin de fichier (EOF) et donc s’arrête, alors qu’avec un « ?> », il continue de parser le fichier après, même s’il n’y a rien.

    Après niveau perf ça doit représenter peanuts mais bon 😉

  • Bon, je me doute que ton article m’aurait aidée, malheureusement je n’en comprends pas grand chose, tant pis 🙁

  • @Aratta Essaie ce qui ne concerne pas le code :
    – Désactiver X-Powered-By.
    – output_buffering on

    🙂

  • @DarkLg: n’y connaissant rien du tout, je galérais quand même 😉
    J’ai juste euh trifouillé un peu le wp-config.php, en refaisant le retour à la ligne entre la 1ere et la 2eme ligne.
    Miracle, ça a marché, grand mystère, alors que c’est pareil qu’avant….

  • Bonjour,
    Juste pour vous informez que j’ai aussi eu cette erreur.
    Elle venait du fait que certains fichiers php étaient encodés en ut8 avec BOM au lieu d’ut8 sans BOM. En mettant tous mes fichiers php avec l’encodage ut8 sans BOM, l’erreur a disparu…
    J’ai mis une demi-journée à comprendre!

  • Merci beaucoup pour votre retour !
    En effet, c’est un vecteur d’erreurs que je m’empresse de rajouter à la liste.

  • Bonjour, je confirme les dires de gloup. Le problème provient de l’encodage des caractères. Pour y avoir passé presque une heure a galérer et a mordre mon crayon, bizarrement je trouve ça plutot bête…

    Par contre, autre bizarrerie :

    ma page php comprend plusieurs modules, appelés par des ‘include’
    Ma grande page est en UTF8 sans BOM
    (j’aperçois un probleme au haut de ma page, comme un décalage vers le haut).

    En ajoutant un de mes modules (a savoir une page php indépendante) avec un encodage UTF8, miracle ma page est de nouveau normale!

    Si quelqu’un connait la solution, je suis preneur! 🙂

    (sur hebergeur 1and1)

  • Salut, merci pour cet article. Il m’a été d’une grande aide. JOLI TRAVAIL !

  • Ce que j’ai lu est intéressant, j’ai essayé certaines choses qui n’ont malheureusement pas fonctionné pour mon cas. Je préciserai juste que parfois, vous avez beau chercher l’espace avant , il n’est tout simplement pas visible. Cela peut poser problème pour un fichier de config permettant l’accès à la base de donnée. Dans ce cas, si vous modifiez votre fichier de config sous notepad, enregistrez le en mode ANSI afin de régler ce problème. Ca a déjà fonctionné pour moi.

  • Merci à Gloup pour son commentaire sur l’UTF-8 sans BOM ! J’ai passé un jour complet avant de tomber sur ce blog et de résoudre mon problème… 😀

    Travailler sous windows, c’est navrant quand-même… XD

    Merci pour ce billet en tout cas !

  • Bonjour,

    C’est vrai que cette erreur est vraiment une perte de temps ! Cela fait 2 jours que je ne savais pas quoi faire et en fait la même chose que Jaggernot en remettant le fichier config.php en mode ANSI au lieu de UFT8 sans BOM… Cherchez pas à comprendre ça a marché !

  • Merci beaucoup, j’avais un problème de balise <?php qui n'étais pas collé au bord de ma feuille, c"est donc résolu ! 😀
    Je vais pouvoir afficher mes commentaires sur mon site!

  • Pour moi, après avoir vérifié mon code sans résultat, j’ai finalement ajouté un ob_start(); ob_end_flush(); et miracle ! ça marche !

    Merci 🙂

    Pour info, je suis hébergée chez Amen…

  • Bonjour,

    Je vous colle mon code, j’ai toujours 3 erreurs Cannot modify header information – headers already sent by malgrès avoir mis ob_start(); et ob_end_flush();
    Si vous pouvez m’aider merci d’avance 🙂

    Confirmation création

    <?php
    ob_start();

    // Une fois le formulaire envoyé
    if(isset($_POST["BT_Envoyer"]))
    {
    // Vérification de la validité des champs
    if(!ereg("^[A-Za-z0-9_]{4,20}$", $_POST["TB_Nom_Utilisateur"]))
    {
    $message = "Votre nom d'utilisateur doit comporter entre 4 et 20 caractères\n »;
    $message .= « L’utilisation de l’underscore est autorisée »;
    print $message;
    }
    elseif(!ereg(« ^[A-Za-z0-9]{4,}$ », $_POST[« TB_Mot_de_Passe »]))
    {
    $message = « Votre mot de passe doit comporter au moins 4 caractères »;
    print $message;
    }
    else
    {
    //connexion au serveur MySQL
    $db = mysql_connect(« localhost », « root », «  ») or die (« erreur de connexion ».mysql_error());

    //ouverture de la DB
    mysql_select_db(« materielpc2 », $db) or die (« erreur de connexion a la base materielpc2″);

    // Sélection de l’utilisateur concerné
    $result = mysql_query
    ( »
    SELECT ID_Utilisateur, Nom_Utilisateur, Mot_de_Passe
    FROM comptes_utilisateurs
    WHERE Nom_Utilisateur = ‘ » . $_POST[« TB_Nom_Utilisateur »] . « ‘
    « );

    // Si une erreur survient
    if(!$result)
    {
    $message = « Une erreur est survenue lors de la tentative de connexion »;
    print $message;
    }
    else
    {
    // Si aucun utilisateur n’a été trouvé
    if(mysql_num_rows($result) == 0)
    {
    $message = « Le nom d’utilisateur  » . $_POST[« TB_Nom_Utilisateur »] .  » n’existe pas »;
    print $message;
    }
    else
    {
    // Récupération des données
    $row = mysql_fetch_array($result);

    // Vérification du mot de passe
    if(md5($_POST[« TB_Mot_de_Passe »]) != $row[« Mot_de_Passe »])
    {
    $message = « Votre mot de passe est incorrect »;
    print $message;
    }
    else
    {
    // Définition du temps d’expiration des cookies
    $expiration = empty($_POST[« CB_Connexion_Automatique »]) ? 0 : time() + 90 * 24 * 60 * 60;

    // Création des cookies
    setcookie(« ID_Utilisateur », $row[« ID_Utilisateur »], $expiration, « / »);
    setcookie(« Nom_Utilisateur », $row[« Nom_Utilisateur »], $expiration, « / »);

    // Fermeture de la connexion à la base de données
    mysql_close();

    // Redirection de l’utilisateur
    header(« Location: index.php »);
    }
    }
    }
    }
    }
    ob_end_flush();
    ?>

  • @Francois Avez-vous essayé toutes les autres techniques expliquées plus haut ?
    L’affichage d’une page de confirmation de connexion plutôt qu’une redirection vers l’index n’est-il pas plus user-friendly ( et judicieux pour ce script ? )

  • Je viens d’être confronté à ce type d’erreur.

    Le problème venais du fichier php enregistré en UTF8.
    En changeant l’encodage en UTF8 sans Bom, je n’ai plus de problème

    Une solution de plus à cette liste. 😉

  • Je vous relercie infinimenttttttttttttttttttttttttttttttttttttttttttttttttt!! ma faute c’était juste que j’ai laissé un simple echo que j’ai écrit pour teste!!

  • Rha, j’y ai passé plusieurs heures pour un sacré UTF-8 ?! T__T

    Merci beaucoup en tous cas !

  • merci à tous les dévoués de la cause informatique et du partage!

    j’ai pris notepad++ et fais la conversion en UTF8 sans BLOM…
    Et là plus de message d’erreur…

  • super j’ai ré-enregistré mon fichier config.php en ANSI et tout remarche.
    Merci!

  • Salut,

    Un grand merci pour cet article, pour ma part, j’ai viré tous les espaces et cela refonctionne.

    Vraiment étrange car l’erreur est arrivée comme un cheveu sur la soupe : ça fonctionnait la veille, je n’ai touché à rien et PAF, erreur PHP.

    @+

  • Un article très utile!!!

    Pour ma part, il suffisait d’enlever les sauts de ligne (inutiles) qu’il y avait en bas de la page functions.php

    Merci !!

  • Un grand merci pour cet article, très instructif !
    Pour ma part l’ajout de ob_start(); et ob_end_flush(); m’a résolu mon problème.
    Encore un grand merci pour ton partage !!!
    😉

  • Bonjour à tous,
    Débutant en php mysql, j’avais le même problème parce que ce je voulais envoyer un cookie en plein milieu d’une page php. Je dois préciser que ma page contient du html, du javascript (tant qu’à faire), et du php. Ca n’est sans doute pas la façon la plus clean de faire mais bon…
    J’ai essayé un tas de trucs (dont les fonctions ob_start() et ob_end_flush() mais placés en début et in fin du code php, ça ne fonctionnait pas).
    J’ai pris plein de cachets d’aspirine, et enfin LA solution :
    J’ai placé le en tout début de ma page avant la balise html et en toute fin de page après la balise de fermeture html.
    Si cela peut servir à quelqu’un qui serait dans le même cas que moi…
    Tchouss !

  • Erreur aussi qui venait de l’encodage UTF8 avec BLOOM. Merci gloup pour cette remontée.
    Par contre j’aimerai bien savoir ce qu’il se passe lors de cette encodage pour que ca génère une telle erreur.

  • Bonjour,
    pour moi, c’est bizarre.
    site en wordpress local : tout est ok
    transfert chez ovh, que des merdes.
    je résous enfin les premières erreurs pour afficher le site; YES.
    Je veux accéder à la partie admin et rebelotte ; cette erreur avec le fichier wp-config.php ; pour tant c’est bien le même que pour la partie foreground !

    Comrpends rien

    je télécharge notepad++ car komodo ,pfff je vois pas le « sans bom ».
    j’enregistre
    je transfers
    et …
    yes !!!
    merci!

  • En fait moi, je ne comprend pas pourquoi on obtient cette erreur:
    Tant que toute la page n’a pas été interprétée par php est ce que le serveur web envoie la page web au visiteur?
    Si non, pourquoi il dit qu’il a déjà envoyé les entêtes?
    Bon c’est pour comprendre comment les choses se passent dans le fond; sinon je met toute fonction de modification d’entêtes avant toute sortie d’affichage; même si les explications données ne me convainquent pas.

  • Merci bien pour votre réponse rapide:
    Mais Tant que toute la page n’a pas été interprétée par php est ce que le serveur web envoie la page web au visiteur?

  • Au secours… Comment fait-on quand malheureusement tout cela s’apparente à du chinois pour nous ?
    J’ai bien essayé de faire les choses indiquées mais…
    Et même ce qui ne concerne pas le code
    « – Désactiver X-Powered-By.
    – output_buffering on »
    je ne vois pas du tout ce que c’est…
    Désolée d’être aussi nulle en la matiere et de tout de meme solliciter votre aide…

  • Quelques pistes simples :
    – Bien regarder le message d’erreur, si une ligne est indiquée.
    – Si une des fonctions indiquées se trouve après un « echo » ou du code html ( ?> … http://www.siteduzero.com/tutoriel-3-14668-concevez-votre-site-web-avec-php-et-mysql.html )

  • Salut à tous moi j’ai eu également ce problème et céla m’a pris une journée entière mais je pense que cet article à resolut mon problème. En fait à l’aide de notepad++ j’en convertis toutes mes pages en UTF-8 san DOM puis j’ai desactivé output buffering en faisant merci à tous: vive la programmation vive le partage.

  • Hello,

    J’aimerai corriger les erreurs mais je ne parviens même pas à me logger sur mon blog. Comment faire?
    Merci d’avance pour votre aide !

  • Même avec un article datant de plus de 5 ans cela fonctionne !! Un grand merci 🙂

  • Hello,
    Je remonte le sujet car je ne me sors pas du même problème.
    Suis pas un pro du php donc ce n’est pas simple ..
    Question: un site s’affiche très correctement chez OVH et une fois transféré chez CLARANET c’est le bazar. Impossible d’afficher la page d’accueil j’ai ce message:
    Warning: Cannot modify header information – headers already sent by (output started at /web/sites/clarahost-fr/2/166/186990/public/www/wp-content/themes/twentyeleven/functions.php:633) in /web/sites/clarahost-fr/2/166/186990/public/www/wp-includes/pluggable.php on line 876
    Un coup de main peut-être? 🙂

  • Il semble qu’il y ait un echo «  »; ou un espace au mauvais endroit dans le fichier functions.php de votre thème.

  • Merci merci, je vais pouvoir explorer plus en détail le fichier 🙂
    Je ne savais même pas où chercher …
    Je reviens pour des nouvelles.

  • Et bah c’est pas gagné ….
    Comme dit plus haut le php n’est pas ma tasse de thé, alors même en regardant de très prêt je ne vois rien.
    Ce qui me surprend c’est que ça passe très bien chez OVH et pas chez CLARANET ???

  • Merci énormément, je bugais pour rien !!!!!! Un saut à la ligne au début du fichier, et ça bloquait tout ! Merci en tout cas pour cette article !!!

  • Bonjour,
    Malgré toutes les recherches et les explications données je n’y arrivai pas. Je ne voyais pas non plus comment être sûr de mes formats aveec mes éditeurs de texte.
    Alors en désespoir de cause et pensant que c’était bien un problème de génération manuelle du Config.php qui posait problème je l’ai renommé (voire on peut le supprimer) et relancé l’appel de la page d’accueil du site. WordPress m’a alors demandé de générer mon config.php, absent, ce que j’ai fait, et là ça a fonctionné. Faites donc confiance à WordPress pour générer correctement votre config.php.
    C’est la méthode la plus simple et efficace que j’ai trouvé. .

  • Bonjour,

    J’ai cette erreur depuis que j’ai créé un fichier php.ini pour augmenter l’upload sur wordpress.

  • Super ! Grâce à ton message, j’ai pu retrouver dans quel fichier pouvait être mon erreur, et j’avais des espaces en trop après le ?> de functions.php
    Merci pour l’article !

  • Merci, pour ma part, c’était un espace et un commentaire avant le code php, avant le header. Ur le server ça marchait mais en local avec MAMP non.
    Merci encore.

  • Merci pour votre aide.
    Mon problème a été resolu par la solution suivante:
    Tout a été tenté, rien ne marche ?
    Ajoutez tout en haut du fichier PHP appelé la fonction : ob_start();
    Ajoutez tout en bas du fichier PHP appelé la fonction : ob_end_flush();
    Explication : ob_start va retenir l’envoi de données, et ob_end_flush les liberera 🙂
    Cette « bidouille » permet d’envoyer des cookies en plein milieu d’une page, et d’autres choses pas très nettes

  • Merci pour cet article, j’ai pu me débloquer avec ob_start(); et ob_end_flush();. Mais que veux-tu dire par « d’autres choses pas très nettes » ?