Maison > Questions et réponses > le corps du texte
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粉0716024062023-10-10 11:29:08
Envoyez quoi que ce soit avant d'envoyer les en-têtes HTTP (utilisez setcookie
或 header
). 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.
3F 3C
开头。您可以安全地从文件开头删除 BOM EF BB BF
. echo
、printf
、readfile
、passthru
、 之前的代码>
etc. display_errors
display_errors
php.ini属性已设置。 php 不会因程序员错误而崩溃,而是默默地修复错误并发出警告。虽然您可以修改 display_errors
php.ini est définie. Au lieu de planter à cause d'une erreur du programmeur, php corrige silencieusement l'erreur et émet un avertissement. Bien que vous puissiez modifier la configuration display_errors
ou error_reporting$_POST['input']
而不使用 empty
或 isset
进行测试是否设置了输入),或者使用未定义的常量而不是字符串文字(如 $_POST[input]
Une cause fréquente est l'accès à des éléments non définis dans le tableau (par exemple $_POST['input']
sans utiliser empty
isset
$_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
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粉0879514422023-10-10 09:54:05
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 :
En-tête
标题
/ header_remove
/ header_remove
session_start
session_start
/ session_regenerate_id
/ session_regenerate_id
setcookie
setcookie
/ setrawcookie
/ setrawcookie
La sortie peut être :
Involontaire :
之前或 ?>
Délibérément :
print
、echo
et autres fonctions qui produisent une sortie 代码之前的原始
partie.
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-8PHP 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 (print
、echo
、,
), 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.
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 :
print
和 echo
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
打印
、echo
、printf
、vprintf
trigger_error
、ob_flush
、ob_end_flush
、var_dump
、print_r
readfile
、passthru
、flush
、imagepng
、imagejpeg
Et d'autres fonctions définies par l'utilisateur.
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.
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.
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.
Il existe également des outils automatisés pour vérifier et réécrire les fichiers texte
(sed
/awk
sed
/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.
后有空格?>
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.)
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.
gzip
Paramètres d'encodage du flux
ou ob_gzhandler
. extension=
à double charge
Générez des messages de démarrage/avertissement PHP implicites. 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.
Si vous vous basez sur php.ini
禁用了 error_reporting
或 display_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.
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.
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.
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 :
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.
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 :
baliseSi 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.
Comme alternative, Redirections JavaScript Disponible 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. )
setcookie()
和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.)