86 votes

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

Je me débats avec cette erreur depuis un moment maintenant.

Au départ, j'ai simplement pensé qu'il s'agissait d'un espace blanc, mais après une recherche plus approfondie, je pense qu'il s'agit peut-être d'un problème similaire à celui-ci :

Recherchez toutes les déclarations qui pourraient envoyer une sortie à l'utilisateur avant cette déclaration d'en-tête. Si vous en trouvez une ou plusieurs, modifiez votre code pour placer la déclaration d'en-tête avant elles. Les expressions conditionnelles complexes peuvent compliquer la question, mais elles peuvent aussi aider à résoudre le problème. Considérez une expression conditionnelle en haut du script de PHP qui détermine la valeur de l'en-tête le plus tôt possible et la fixe à cet endroit.

Je suppose que l'en-tête include est à l'origine du problème, ainsi que la fonction header(), mais je ne sais pas comment réorganiser le code pour éliminer cette erreur.

Comment 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];
        }
    }
?>

1 votes

Qu'est-ce que header.php ressembler ?

2 votes

Lieu include_once 'header.php'; après le if ($username... chaîne if/else afin que les en-têtes de redirection ne soient pas appelés après la sortie de l'en-tête HTML.

2 votes

En supposant qu'il n'y a pas d'espace avant le < ? dans le fichier que vous avez listé, il y a une sortie qui se produit dans le fichier header.php, intentionnelle ou non. Si header.php est censé produire une sortie, vous devez placer la condition de connexion avant d'inclure header.php, sinon vous devrez éliminer toute sortie créée dans le fichier header.php. Les coupables les plus probables, d'après mon expérience, sont les espaces blancs supplémentaires soit avant la balise d'ouverture < ? soit après la balise de fermeture ?>. Il est certain que si vous ne voyez pas de caractères avant l'erreur, c'est que vous recherchez un espace blanc.

238voto

SamHennessy Points 1736

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 le corps du message. Ensuite, à la fin de votre scripts, faites toute sortie dont vous avez besoin.

La solution très rapide pour votre problème sera d'ajouter

ob_start();

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

Ceci active la fonction de mise en tampon de la sortie de PHP. En PHP, lorsque vous sortez quelque chose (faire un echo ou un print), il doit envoyer les en-têtes HTTP à ce moment-là. Si vous activez la mise en tampon de la sortie, vous pouvez sortir dans le script mais PHP n'a pas à envoyer les en-têtes jusqu'à ce que le tampon soit vidé. Si vous l'activez et que vous ne le désactivez pas, PHP videra automatiquement tout ce qui se trouve dans le tampon après que le script ait terminé son exécution. Il n'y a vraiment aucun mal à l'activer dans presque tous les cas et pourrait vous donner une petite augmentation des performances dans certaines configurations.

Si vous avez accès à la modification de votre fichier de configuration php.ini, vous pouvez trouver et modifier ou ajouter les éléments suivants

output_buffering = On

Ceci désactivera la mise en tampon de la sortie sans avoir besoin d'appeler ob_start().

Pour en savoir plus sur la mise en mémoire tampon des sorties, consultez le site suivant http://php.net/manual/en/book.outcontrol.php

0 votes

@SamHennesy où dois-je ajouter ob_start() sous l'en-tête ou au début de la page ?

1 votes

@Sharif , faites-le le plus tôt possible. Si c'est le début de la page, alors c'est ça. La plupart du temps, il n'y a pas de mal à appeler ob_start().

0 votes

Est-ce une bonne pratique ? Je veux dire que depuis PHP envoie une erreur, cela signifie-t-il qu'il y aurait une meilleure façon de procéder ?

10voto

Saiyam Patel Points 933

Vérifiez quelque chose avec echo , print() o printr() dans le fichier d'inclusion, header.php .

Il se peut que ce soit là le problème OU si un fichier MVC, alors vérifiez le nombre d'espaces après ?> . Cela pourrait également poser un problème.

6voto

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

Si vous voulez faire cela, cherchez la mise en mémoire tampon de la sortie.

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

6voto

James C Points 9120

Il y a quelques problèmes avec votre header() des appels, dont l'un pourrait causer des problèmes

  • Vous devriez mettre un exit() après chacun des header("Location: sinon l'exécution du code se poursuivra
  • Vous devez avoir un espace après le : de sorte qu'il se lit "Location: http://foo"
  • Il n'est pas valide d'utiliser une URL relative dans un fichier de type Location vous devez former une URL absolue comme suit http://www.mysite.com/some/path.php

0 votes

Mais mes toutes les urls relatives dans header() fonctionnent sauf une.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X