Maison  >  Questions et réponses  >  le corps du texte

Façons de corriger l’erreur « En-têtes déjà envoyés » en PHP

Lors de l'exécution de mon script, j'obtiens plusieurs erreurs comme celle-ci :

Attention : Impossible de modifier les informations d'en-tête - en-tête déjà envoyé par /some/file.php (La sortie commence à /some/file.php:12)

La ligne mentionnée dans le message d'erreur contient l'appel header()setcookie().

Quelle pourrait en être la raison ? Comment le résoudre?

P粉210405394P粉210405394349 Il y a quelques jours494

répondre à tous(2)je répondrai

  • P粉071602406

    P粉0716024062023-10-10 11:29:08

    Envoyez quoi que ce soit avant d'envoyer les en-têtes HTTP (utilisez setcookieheader). Les raisons courantes pour lesquelles quelque chose est affiché avant les en-têtes HTTP sont :

    • Espaces inattendus, généralement au début ou à la fin d'un fichier, comme ceci :

               Pour éviter cela, omettez simplement la fin ?> - ce n'est pas nécessaire de toute façon.

    pour tester si l'entrée est définie), Ou utilisez une constante non définie au lieu d'une chaîne littérale (comme dans $_POST[input], notez les guillemets manquants).

    Activez la mise en mémoire tampon de sortieob_start 后的所有输出都缓冲在内存中,直到您释放缓冲区,例如与 ob_end_flush devrait faire l'affaire ; toutes les sorties après l'appel de ob_start

    sont mises en mémoire tampon jusqu'à ce que vous libériez le tampon, par exemple avec ob_end_flush

    .

    🎜Cependant, même si la mise en mémoire tampon de sortie peut éviter ces problèmes, vous devez vraiment déterminer pourquoi votre application génère le corps HTTP avant les en-têtes HTTP. C'est comme répondre au téléphone et discuter de votre journée et de la météo, puis dire à l'appelant qu'il a composé le mauvais numéro. 🎜

    répondre
    0
  • P粉087951442

    P粉0879514422023-10-10 09:54:05

    Aucune sortie avant l'envoi des en-têtes !

    Les fonctions qui envoient/modifient les en-têtes HTTP doivent être appelées avant qu'une sortie ne soit effectuée. Résumé⇊ Sinon l'appel échoue :

    Certaines fonctions qui modifient les en-têtes HTTP sont :

    La sortie peut être :

    • Délibérément :

      • printecho et autres fonctions qui produisent une sortie
      • 代码之前的原始 partie.

    Pourquoi cela arrive-t-il ?

    Il est nécessaire de comprendre pourquoi les en-têtes doivent être envoyés avant la sortie Voir typique HTTP répondre. Le script PHP génère principalement du contenu HTML et transmet également un Ensemble d'entêtes HTTP/CGI envoyés au serveur web :

    HTTP/1.1 200 OK
    Powered-By: PHP/5.3.7
    Vary: Accept-Encoding
    Content-Type: text/html; charset=utf-8
    
    PHP page output page
    

    Content

    Some more output follows...

    and

    Page/Sortie suit toujours titre. PHP doit réussir L'en-tête est d'abord envoyé au serveur Web. Cela ne peut être fait qu'une seule fois. Ils ne peuvent plus être modifiés après double emballage.

    Lorsque PHP reçoit la première sortie (printecho, ), il sera Actualisertous les en-têtes collectés. Après cela, il peut envoyer toutes les sorties Il le veut. Mais l'envoi d'autres en-têtes HTTP n'est pas possible.

    Comment savoir où se produit une sortie prématurée ?

    header() L'avertissement contient toutes les informations pertinentes Cause du problème de positionnement :

    Ici, « ligne 100 » fait référence au script qui header() appelle et échoue.

    Le commentaire "la sortie commence à " entre parenthèses est plus important. Il représente la source de la sortie précédente. Dans cet exemple, c'est auth.php et ème ligne 52. C'est là qu'il faut rechercher une sortie prématurée.

    Raisons typiques :

    1. Imprimer et écho

      La sortie intentionnelle de l'instruction

      printecho mettra fin à la possibilité d'envoyer des en-têtes HTTP. Le processus de candidature doit être restructuré pour éviter cette situation. Utilisation de la fonction et des solutions de modèles. Assurez-vous que l'appel header() a lieu avant le message Tout est écrit.

      Les fonctions qui produisent une sortie incluent

      • 打印echoprintfvprintf
      • trigger_errorob_flushob_end_flushvar_dumpprint_r
      • readfilepassthruflushimagepngimagejpeg


      Et d'autres fonctions définies par l'utilisateur.

    2. Zone HTML originale

      La partie HTML non analysée du fichier .php est également sortie directement. Il faut faire attention aux conditions du script qui déclencheront l'appel header() Avant tout bloc original.

      
      
      

      Utilisez un schéma de modèle pour séparer le traitement de la logique de sortie.

      • Placez le code de gestion du formulaire au-dessus des scripts.
      • Utilisez des variables de chaîne temporaires pour différer les messages.
      • La logique de sortie réelle et la sortie HTML mixte devraient être les dernières.

    3. L'espace avant signifie "script.php Ligne 1" avertissement

      Si l'avertissement fait référence à la sortie en ligne1, alors principalement Début espace avant la balise d'ouverture , texte ou HTML.

      
      

      De même, cela peut se produire avec des scripts ou des sections de script supplémentaires :

      ?>
      
      
      

      PHP prend en fait un single saut de ligne après la fermeture de la balise. mais ce ne sera pas le cas Compense le déplacement de plusieurs nouvelles lignes, tabulations ou espaces dans ces espaces.

    4. NOMME UTF-8

      Les nouvelles lignes et les espaces peuvent à eux seuls poser problème. Mais il y a aussi des « invisibles » Séquences de caractères pouvant provoquer cela. Le plus célèbre est UTF-8 BOM (Marque d'ordre des octets) La plupart des éditeurs de texte ne l'affichent pas. C'est une séquence d'octets EF BB BF,对于 UTF-8 编码的文档来说,它是可选且冗余的。然而 PHP 必须将其视为原始输出。它可能在输出中显示为字符  (si le client interprète le document comme Latin-1) ou une « poubelle » similaire.

      Surtout les éditeurs graphiques et les IDE basés sur Java ne le remarquent pas Être présent. Ils ne le visualisent pas (comme l'exige la norme Unicode). Cependant, la plupart des programmeurs et éditeurs de consoles :

      Cela facilite la détection précoce des problèmes. D'autres éditeurs peuvent reconnaître Il est présent dans le menu Fichier/Paramètres (Notepad++ sous Windows reconnaît et Problème résolu), Une autre option pour vérifier l'existence de la nomenclature est d'utiliser l'Hex Editor. Sur les systèmes *nix hexdump généralement disponibles, Sinon, simplifiez l'examen des variantes graphiques de ces questions et d'autres :

      Une solution simple consiste à configurer votre éditeur de texte pour qu'il enregistre les fichiers au format "UTF-8 (pas de nomenclature)". Ou une nomenclature similaire. Souvent, les débutants auront recours à la création de nouveaux fichiers, puis à copier et coller le code précédent.

      Utilitaire de correction

      Il existe également des outils automatisés pour vérifier et réécrire les fichiers texte (sed/awksed/awk重新编码 ou recode). Pour PHP, plus précisément la balise phptags plus rangée. Il réécrit les balises de fermeture et d'ouverture sous forme longue et courte et est également simple. Correction des espaces de début et de fin, des problèmes de nomenclature Unicode et UTF-x :

      phptags  --whitespace  *.php

      Utilisation sûre sur des répertoires d'inclusion ou de projet entiers.

    5. 后有空格?>

      Si la source de l'erreur est mentionnée plus tard Fermer ?> Eh bien, c'est ici qu'un texte vierge ou brut est écrit. La balise de fermeture PHP ne termine pas l'exécution du script pour le moment. Tous les caractères de texte/espace après seront écrits en tant que contenu de la page toujours.

      Il est généralement recommandé, notamment aux débutants, de suivre ?> PHP La balise de fermeture doit être omise. Cela évite une petite fraction de ces cas. (Très courant, les scripts include()d sont les coupables.)

    6. La source de l'erreur s'appelle "Ligne inconnue 0"

      S'il n'y a pas de source d'erreur, il s'agit généralement d'une extension PHP ou d'un paramètre php.ini Béton.

      • Parfois gzip Paramètres d'encodage du flux ou ob_gzhandler.
      • Mais il peut aussi s'agir de n'importe quel module extension= à double charge Générez des messages de démarrage/avertissement PHP implicites.

    7. Message d'erreur précédent

      Si une autre instruction ou expression PHP provoque un message d'avertissement ou Une note est imprimée, ce qui est également considéré comme une sortie prématurée.

      Dans ce cas, vous devez éviter les erreurs, Retardez l'exécution de l'instruction ou supprimez les messages en utilisant par ex. isset()isset()@() ou @() - Quand l’un ou l’autre n’empêche pas le débogage ultérieur.

    Aucun message d'erreur

    Si vous vous basez sur php.ini 禁用了 error_reportingdisplay_errors, Aucun avertissement n’apparaîtra alors. Mais ignorer l'erreur ne résout pas le problème partir. Toujours impossible d'envoyer des en-têtes après une sortie prématurée.

    Alors quand header("Location: ...") une redirection échoue silencieusement, c'est très grave Un avertissement de sonde est recommandé. Réactivez-les avec deux commandes simples En plus du script d'appel :

    error_reporting(E_ALL);
    ini_set("display_errors", 1);

    ou set_error_handler("var_dump"); si tout le reste échoue.

    En parlant d'en-têtes de redirection, vous devriez toujours utiliser des expressions comme celle-ci Voici le chemin de code final :

    exit(header("Location: /finished.html"));

    Il est préférable d'être une fonction pratique qui imprime les messages des utilisateurs Si header() échoue.

    Mise en mémoire tampon de sortie comme solution de contournement

    PHP Tampon de sortie est une solution de contournement pour atténuer ce problème. Cela fonctionne généralement de manière fiable, mais cela ne devrait pas Remplacer la structure d'application correcte et séparer la sortie du contrôle logique. Son objectif réel est de minimiser les transferts fragmentés vers le serveur Web.

    1. output_buffering= Pourtant, les paramètres aident. Configurez-le dans php.ini Ou via .htaccess Même .user.ini Configuration FPM/FastCGI moderne.
      L'activation de cette option permettra à PHP de mettre en mémoire tampon la sortie au lieu de la transmettre immédiatement au serveur Web. PHP peut donc agréger les en-têtes HTTP.

    2. On peut aussi l'appeler en appelant ob_start(); au-dessus du script appelant. Cependant, il n'est pas très fiable pour plusieurs raisons :

      • Même si démarre le premier script, un espace ou La nomenclature peut être brouillée et invalidée avant le rendu.

      • Il peut masquer les espaces de la sortie HTML. Cependant, une fois que la logique de l'application tente d'envoyer du contenu binaire (comme une image générée), La sortie étrangère en mémoire tampon devient un problème. (nécessite ob_clean()) comme solution de contournement supplémentaire. )

      • La taille du tampon est limitée et peut facilement déborder si elle est laissée à la valeur par défaut. Cette situation n'est pas rare, difficile à suivre quand ça arrive.

    Par conséquent, les deux méthodes peuvent devenir peu fiables, en particulier lors du basculement entre les deux. Configuration du développement et/ou serveur de production. C'est pourquoi la mise en mémoire tampon de sortie est Largement considéré comme n'étant qu'une béquille/strictement une solution de contournement.

    Voir aussi Exemples d'utilisation de base Dans le manuel, et plus d'avantages et d'inconvénients :

    Mais ça marche sur d'autres serveurs ! ?

    Si vous n'avez pas reçu l'avertissement d'en-tête auparavant, mise en mémoire tampon de sortie Paramètres php.ini déjà changé. Il n'est peut-être pas configuré sur le serveur actuel/nouveau.

    Utilisez headers_sent()检查

    Vous pouvez toujours utiliser headers_sent() pour détecter si Il est toujours possible... d'envoyer des en-têtes. Ceci est utile pour l'impression conditionnelle informations ou appliquer une autre logique de secours.

    if (headers_sent()) {
        die("Redirect failed. Please click on this link: ");
    }
    else{
        exit(header("Location: /user.php"));
    }

    Une solution de repli utile est :

    Cependant, les deux méthodes produisent des solutions de repli acceptables lorsque le véritable en-tête HTTP() L'appel a échoué. Idéalement, vous combinez toujours cela avec un message convivial, Liens cliquables en dernier recours. (Par exemple, http_redirect() L'extension PECL le fait. )

    Pourquoisetcookie()session_start()est également concerné

    setcookie()session_start() 都需要发送 Set-Cookie: En-têtes HTTP. Par conséquent, les mêmes conditions s'appliquent et un message d'erreur similaire sera généré Utilisé en cas de sortie prématurée.

    (Bien entendu, ils sont également concernés par la désactivation des cookies dans votre navigateur Même des problèmes d’agence. La fonctionnalité de session s'appuie évidemment aussi sur la gratuité Espace disque et autres paramètres php.ini, etc.)

    Plus de liens

    répondre
    0
  • Annulerrépondre