web-dev-qa-db-fra.com

Avertissement: impossible de modifier les informations d'en-tête - en-têtes déjà envoyés par ERROR

Duplication possible: En-têtes déjà envoyés par PHP

Je lutte avec cette erreur depuis un moment maintenant.

Pour commencer, je pensais simplement qu'il s'agissait d'un espace, mais après d'autres recherches, je pense que cela pourrait être un problème similaire à celui-ci:

Recherchez toutes les instructions susceptibles d'envoyer une sortie à l'utilisateur avant cette instruction d'en-tête. Si vous en trouvez un ou plusieurs, modifiez votre code pour déplacer l'instruction d'en-tête devant eux. Des instructions conditionnelles complexes peuvent compliquer le problème, mais elles peuvent également aider à résoudre le problème. Considérez une expression conditionnelle en haut du script PHP qui détermine la valeur d'en-tête le plus tôt possible et la définit à cet endroit.

J'imagine que l'en-tête include pose le problème avec l'en-tête (), mais je ne suis pas sûr de savoir comment réorganiser le code pour supprimer cette erreur.

Comment puis-je supprimer l'erreur?

<?php
    $username = $password = $token = $fName = "";

    include_once 'header.php';

    if (isset($_POST['username']) && isset($_POST['password']))
        $username = sanitizeString($_POST['username']);

    $password = sanitizeString($_POST['password']); //Set temporary username and password variables
    $token    = md5("$password"); //Encrypt temporary password

    if ($username != 'admin')
    {
        header("Location:summary.php");
    }
    elseif($username == 'admin')
    {
        header("Location:admin.php");
    }
    elseif($username == '')
    {
        header("Location:index.php");
    }
    else
        die ("<body><div class='container'><p class='error'>Invalid username or password.</p></div></body>");

    if ($username == "" || $token == "")
    {
        echo "<body><div class='container'><p class='error'>Please enter your username and password</p></div></body>";
    }
    else
    {
        $query = "SELECT * FROM members WHERE username='$username'AND password = '$token'"; //Look in table for username entered
        $result = mysql_query($query);
        if (!$result)
            die ("Database access failed: " . mysql_error());
        elseif (mysql_num_rows($result) > 0)
        {
            $row = mysql_fetch_row($result);
            $_SESSION['username'] = $username; //Set session variables
            $_SESSION['password'] = $token;

            $fName = $row[0];
        }
    }
?>
84
Rob

La réponse à long terme est que toutes les sorties de vos scripts PHP doivent être mises en mémoire tampon dans des variables. Cela inclut les en-têtes et la sortie du corps. Puis, à la fin de vos scripts, effectuez les sorties dont vous avez besoin.

La solution rapide à votre problème consistera à ajouter

ob_start();

comme la toute première chose dans votre script, si vous en avez seulement besoin dans ce script. Si vous en avez besoin dans tous vos scripts, ajoutez-le comme la première chose dans votre fichier header.php.

Cela active la fonctionnalité de tampon de sortie de PHP. Dans PHP lorsque vous exportez quelque chose (faire un écho ou une impression), il doit envoyer les en-têtes HTTP à ce moment-là. Si vous activez la mise en tampon de sortie, vous pouvez générer le script, mais PHP n'a pas à envoyer les en-têtes tant que la mémoire tampon n'est pas vidée. Si vous l'activez et ne le désactivez pas, PHP videra automatiquement tout le contenu du tampon à la fin de l'exécution du script. Il n’ya vraiment aucun inconvénient à l’activer dans la quasi-totalité des cas et pourrait vous donner une légère augmentation des performances dans certaines configurations.

Si vous avez le droit de modifier votre fichier de configuration php.ini, vous pouvez rechercher et modifier ou ajouter les éléments suivants:

output_buffering = On

Cela désactivera la sortie de la mémoire tampon sans qu'il soit nécessaire d'appeler ob_start ().

Pour en savoir plus sur la mise en mémoire tampon de sortie, consultez http://php.net/manual/en/book.outcontrol.php

235
SamHennessy

Vérifiez quelque chose avec echo, print() ou printr() dans le fichier à inclure, header.php.

Il se peut que ce soit le problème OR s'il existe un fichier MVC, puis vérifiez le nombre d'espaces après ?>. Cela pourrait aussi faire un problème.

10
Saiyam Patel

Vous essayez d'envoyer des informations sur les en-têtes après la sortie du contenu.

Si vous voulez faire cela, cherchez buffering de sortie.

Par conséquent, cherchez à utiliser ob_start();

6
Pierre-Olivier

Il y a quelques problèmes avec vos appels header(), l'un d'eux pouvant être à l'origine de problèmes

  • Vous devez mettre un exit() après chacun des appels header("Location:, sinon l'exécution du code continuera
  • Vous devriez avoir un espace après le : pour qu'il lise "Location: http://foo"
  • L'utilisation d'une URL relative dans un en-tête Location n'est pas valide. Vous devez former une URL absolue telle que http://www.mysite.com/some/path.php.
5
James C