Façons de corriger l'erreur « En-têtes déjà envoyés » en PHP
P粉210405394
P粉210405394 2023-10-09 21:06:28
0
2
479

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'appelheader()setcookie().

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

P粉210405394
P粉210405394

répondre à tous (2)
P粉071602406

Envoyez quoi que ce soit avant d'envoyer les en-têtes HTTP (utilisezsetcookieheader). 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 lamise en mémoire tampon de sortieob_start后的所有输出都缓冲在内存中,直到您释放缓冲区,例如与ob_end_flushdevrait faire l'affaire ; toutes les sorties après l'appel deob_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.
    P粉087951442

    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 :

      • printechoet 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 typiqueHTTPré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-8PHP page output page

    Content

    Some more output follows...

    and

    Page/Sortiesuit toujourstitre. 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 seraActualisertous 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 quiheader()appelleet é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'estauth.phpetème ligne52. C'est là qu'il faut rechercher une sortie prématurée.

    Raisons typiques :

    1. Imprimer et écho

      La sortie intentionnelle de l'instruction

      printechomettra fin à la possibilité d'envoyer des en-têtes HTTP. Le processus de candidature doit être restructuré pour éviter cette situation. Utilisation de la fonctionet des solutions de modèles. Assurez-vous que l'appelheader()a lieu avant le messageTout 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'appelheader()Avanttoutblocoriginal.

                   

      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.phpLigne 1" avertissement

      Si l'avertissement fait référence à la sortie en ligne1, alors principalement Début espaceavant 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 unsinglesaut 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 estUTF-8 BOM(Marque d'ordre des octets)La plupart des éditeurs de texte ne l'affichent pas. C'est une séquence d'octetsEF 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 etProblème résolu), Une autre option pour vérifier l'existence de la nomenclature est d'utiliser l'Hex Editor. Sur les systèmes *nixhexdumpgé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代码>重新编码ourecode). Pour PHP, plus précisément la balisephptagsplus 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 tardFermer?>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éviteune petite fraction de ces cas. (Très courant, les scriptsinclude()dsont 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.

      • ParfoisgzipParamètres d'encodage du fluxouob_gzhandler.
      • Mais il peut aussi s'agir de n'importe quel moduleextension=à 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 surphp.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 quandheader("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);

    ouset_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 Siheader()échoue.

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

    PHPTampon de sortieest 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 dansphp.iniOu via.htaccessMême.user.iniConfiguration 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 appelantob_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 lerendu.

      • 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 aussiExemples d'utilisation de baseDans 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.inidéjà changé. Il n'est peut-être pas configuré sur le serveur actuel/nouveau.

    Utilisezheaders_sent()检查

    Vous pouvez toujours utiliserheaders_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 :

    • HTML balise

      Si votre application est structurellement difficile à corriger, un simple (mais Un peu peu professionnel) La façon d'autoriser la redirection est d'injecter du HTML Balises. La redirection peut être réalisée via :

                   

      Ou court délai :

                   

      Cela entraîne un HTML invalide lorsqu'il est utilisé au-delà de la section. La plupart des navigateurs l'acceptent toujours.

    • Redirection JavaScript

      Comme alternative,Redirections JavaScriptDisponible pour la redirection de page :

      sssccc

      Bien que cette solution soit généralement plus conforme au HTML que la solution de contournement , Cela entraîne une dépendance vis-à-vis des clients compatibles JavaScript.

    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

      Derniers téléchargements
      Plus>
      effets Web
      Code source du site Web
      Matériel du site Web
      Modèle frontal
      À propos de nous Clause de non-responsabilité Sitemap
      Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!