Beim Ausführen meines Skripts werden folgende Fehler angezeigt:
Warnung: Header-Informationen können nicht geändert werden - Header, die bereits von ( Ausgabe gestartet unter /some/file.php:12 ) in /some/file.php in Zeile 23 gesendet wurden
Die in den Fehlermeldungen genannten Zeilen enthalten header()
und setcookie()
ruft auf.
Was könnte der Grund dafür sein? Und wie kann man das beheben?
ob_start
undob_end_clean()
sich hier als nützlich erweisen kann). Sie können dann ein Cookie oder eine Sitzung gleich setzenob_get_contents()
und dannob_end_clean()
den Puffer löschen.safeRedirect
Funktion in meiner PHP-Bibliothek: github.com/heinkasner/PHP-Library/blob/master/extra.phpUTF-8
, aberUTF-8 (Without BOM)
~~~~~~~~~~~Antworten:
Keine Ausgabe vor dem Senden von Headern!
Funktionen, die HTTP-Header senden / ändern, müssen aufgerufen werden, bevor eine Ausgabe erfolgt . summary ⇊ Andernfalls schlägt der Anruf fehl:
Einige Funktionen, die den HTTP-Header ändern, sind:
header
/.header_remove
session_start
/.session_regenerate_id
setcookie
/.setrawcookie
Die Ausgabe kann sein:
Unbeabsichtigt:
<?php
oder nachher?>
Absichtlich:
print
,echo
Und andere Funktionen zum Erzeugen von Ausgang<html>
Abschnitt vorheriger<?php
Code.Warum passiert das?
Um zu verstehen, warum Header vor der Ausgabe gesendet werden müssen, muss eine typische HTTP- Antwort betrachtet werden. PHP-Skripte generieren hauptsächlich HTML-Inhalte, übergeben aber auch eine Reihe von HTTP / CGI-Headern an den Webserver:
Die Seite / Ausgabe folgt immer den Überschriften. PHP muss zuerst die Header an den Webserver übergeben. Das kann es nur einmal. Nach dem doppelten Zeilenumbruch können sie nie mehr geändert werden.
Wenn PHP den ersten Ausgang empfängt (
print
,echo
,<html>
) wird es bündig alle gesammelten Header. Danach kann es alle gewünschten Ausgaben senden. Das Senden weiterer HTTP-Header ist dann jedoch nicht möglich.Wie können Sie herausfinden, wo die vorzeitige Ausgabe stattgefunden hat?
Die
header()
Warnung enthält alle relevanten Informationen zum Auffinden der Problemursache:Hier bezieht sich "Zeile 100" auf das Skript, bei dem der
header()
Aufruf fehlgeschlagen ist.Der Hinweis " Ausgabe gestartet um " in der Klammer ist wichtiger. Es bezeichnet die Quelle der vorherigen Ausgabe. In diesem Beispiel ist es
auth.php
und Linie52
. Dort musste man nach vorzeitiger Ausgabe suchen.Typische Ursachen:
Drucken, Echo
Durch die absichtliche Ausgabe von
print
undecho
Anweisungen wird die Möglichkeit zum Senden von HTTP-Headern beendet. Der Anwendungsfluss muss umstrukturiert werden, um dies zu vermeiden. Verwenden Sie Funktionen und Vorlagenschemata. Stellen Sie sicher, dassheader()
Anrufe erfolgen, bevor Nachrichten ausgeschrieben werden.Zu den Funktionen, die eine Ausgabe erzeugen, gehören:
print
,echo
,printf
,vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
,passthru
,flush
,imagepng
,imagejpeg
unter anderem und benutzerdefinierte Funktionen.
Rohe HTML-Bereiche
Nicht analysierte HTML-Abschnitte in einer
.php
Datei werden ebenfalls direkt ausgegeben. Skriptbedingungen, die einenheader()
Aufruf auslösen , müssen vor allen Rohblöcken notiert<html>
werden.Verwenden Sie ein Vorlagenschema, um die Verarbeitung von der Ausgabelogik zu trennen.
Leerzeichen vor
<?php
für "script.php Zeile 1 " WarnungenWenn sich die Warnung auf die Ausgabe in Zeile bezieht
1
, handelt es sich meistens um führende Leerzeichen , Text oder HTML vor dem öffnenden<?php
Token.Ebenso kann es bei angehängten Skripten oder Skriptabschnitten auftreten:
PHP frisst tatsächlich einen einzelnen Zeilenumbruch nach dem Schließen von Tags auf. Es werden jedoch nicht mehrere Zeilenumbrüche, Tabulatoren oder Leerzeichen ausgeglichen, die in solche Lücken verschoben wurden.
UTF-8-Stückliste
Zeilenumbrüche und Leerzeichen allein können ein Problem sein. Es gibt aber auch "unsichtbare" Zeichenfolgen, die dies verursachen können. Am bekanntesten ist die UTF-8-Stückliste (Byte-Order-Mark), die von den meisten Texteditoren nicht angezeigt wird. Dies ist die Byte-Sequenz
EF BB BF
, die für UTF-8-codierte Dokumente optional und redundant ist. PHP muss es jedoch als Rohleistung behandeln. Es kann als Zeichen
in der Ausgabe (wenn der Client das Dokument als Latin-1 interpretiert) oder als ähnlicher "Müll" angezeigt werden .Insbesondere grafische Editoren und Java-basierte IDEs sind sich ihrer Anwesenheit nicht bewusst. Sie visualisieren es nicht (verpflichtet durch den Unicode-Standard). Die meisten Programmierer und Konsoleneditoren tun jedoch Folgendes:
Dort ist das Problem leicht zu erkennen. Andere Editoren identifizieren möglicherweise das Vorhandensein in einem Datei- / Einstellungsmenü (Notepad ++ unter Windows kann das Problem identifizieren und beheben ). Eine weitere Option zum Überprüfen des Vorhandenseins von Stücklisten besteht darin, auf einen Hexeditor zurückzugreifen . On * nix-Systeme
hexdump
sind normalerweise verfügbar, wenn nicht eine grafische Variante, die die Prüfung dieser und anderer Probleme vereinfacht:Eine einfache Lösung besteht darin, den Texteditor so einzustellen, dass Dateien als "UTF-8 (keine Stückliste)" oder eine ähnliche Nomenklatur gespeichert werden. Oft greifen Neulinge ansonsten dazu, neue Dateien zu erstellen und den vorherigen Code einfach wieder zu kopieren und einzufügen.
Korrekturdienstprogramme
Es gibt auch automatisierte Tools zum Überprüfen und Umschreiben von Textdateien (
sed
/awk
oderrecode
). Für PHP gibt es speziell dasphptags
Tag aufgeräumter . Es schreibt geschlossene und geöffnete Tags in lange und kurze Formulare um, behebt aber auch problemlos führende und nachfolgende Whitespace-, Unicode- und UTF-x-Stücklistenprobleme:Es ist vernünftig, ein gesamtes Include- oder Projektverzeichnis zu verwenden.
Leerzeichen nach
?>
Wenn die Fehlerquelle hinter dem Schließen
?>
steht, wurde hier ein Leerzeichen oder Rohtext geschrieben. Der PHP-Endmarker beendet die Skriptausführung zu diesem Zeitpunkt nicht. Alle Text- / Leerzeichen danach werden weiterhin als Seiteninhalt ausgeschrieben.Insbesondere Neulingen wird allgemein empfohlen, nachfolgende
?>
PHP-Close-Tags wegzulassen. Dies vermeidet einen kleinen Teil dieser Fälle. (Sehr häufig sindinclude()d
Skripte der Schuldige.)Fehlerquelle als "Unbekannt in Zeile 0"
Es ist normalerweise eine PHP-Erweiterung oder eine php.ini-Einstellung, wenn keine Fehlerquelle konkretisiert wird.
gzip
Stream-Codierungseinstellung oder dieob_gzhandler
.extension=
Modul handeln, das eine implizite PHP-Start- / Warnmeldung generiert.Vorhergehende Fehlermeldungen
Wenn eine andere PHP-Anweisung oder ein anderer Ausdruck dazu führt, dass eine Warnmeldung oder ein Hinweis ausgedruckt wird, gilt dies auch als vorzeitige Ausgabe.
In diesem Fall müssen Sie den Fehler vermeiden, die Ausführung der Anweisung verzögern oder die Nachricht mit zB
isset()
oder@()
- unterdrücken, wenn dies das spätere Debuggen nicht behindert.Keine Fehlermeldung
Wenn Sie
error_reporting
oderdisplay_errors
deaktiviert prophp.ini
, dann zeigt keine Warnung auf. Das Ignorieren von Fehlern lässt das Problem jedoch nicht verschwinden. Header können nach vorzeitiger Ausgabe immer noch nicht gesendet werden.Wenn
header("Location: ...")
Umleitungen stillschweigend fehlschlagen, ist es sehr ratsam, nach Warnungen zu suchen. Aktivieren Sie sie mit zwei einfachen Befehlen über dem Aufrufskript erneut:Oder
set_error_handler("var_dump");
wenn alles andere fehlschlägt.Apropos Redirect-Header: Für endgültige Codepfade sollten Sie häufig eine solche Redewendung verwenden:
Vorzugsweise sogar eine Dienstprogrammfunktion, die bei
header()
Fehlern eine Benutzermeldung druckt .Ausgabepufferung als Problemumgehung
Die Ausgabepufferung von PHPs ist eine Problemumgehung, um dieses Problem zu beheben . Es funktioniert oft zuverlässig, sollte jedoch die ordnungsgemäße Strukturierung der Anwendung und die Trennung der Ausgabe von der Steuerlogik nicht ersetzen. Der eigentliche Zweck besteht darin, die Übertragung von Chunks auf den Webserver zu minimieren.
Die
output_buffering=
Einstellung kann trotzdem helfen. Konfigurieren Sie es in der php.ini oder über .htaccess oder sogar .user.ini in modernen FPM / FastCGI-Setups.Durch Aktivieren kann PHP die Ausgabe puffern, anstatt sie sofort an den Webserver weiterzuleiten. PHP kann somit HTTP-Header aggregieren.
Es kann ebenfalls mit einem Aufruf zum
ob_start();
Aufrufen des Aufrufskripts verbunden werden. Was jedoch aus mehreren Gründen weniger zuverlässig ist:Selbst wenn
<?php ob_start(); ?>
das erste Skript gestartet wird, werden Leerzeichen oder Stücklisten möglicherweise zuvor gemischt, wodurch es unwirksam wird .Es kann Leerzeichen für die HTML-Ausgabe verbergen. Sobald die Anwendungslogik jedoch versucht, binären Inhalt (z. B. ein generiertes Bild) zu senden, wird die gepufferte Fremdausgabe zu einem Problem. (Notwendig
ob_clean()
als weitere Problemumgehung.)Der Puffer ist in seiner Größe begrenzt und kann leicht überlaufen, wenn die Standardeinstellungen beibehalten werden. Und das ist auch keine Seltenheit, schwer zu finden, wenn es passiert.
Beide Ansätze können daher unzuverlässig werden - insbesondere beim Wechsel zwischen Entwicklungs-Setups und / oder Produktionsservern. Aus diesem Grund wird die Ausgabepufferung allgemein nur als Krücke / strikte Problemumgehung betrachtet.
Siehe auch das grundlegende Verwendungsbeispiel im Handbuch und weitere Vor- und Nachteile:
Aber es hat auf dem anderen Server funktioniert!?
Wenn Sie die Header-Warnung zuvor nicht erhalten haben, wird die Einstellung php.ini für die Ausgabepufferung verwendet geändert. Es ist wahrscheinlich auf dem aktuellen / neuen Server nicht konfiguriert.
Überprüfen mit
headers_sent()
Sie können jederzeit
headers_sent()
prüfen, ob es noch möglich ist, ... Header zu senden. Dies ist nützlich, um eine Information bedingt auszudrucken oder eine andere Fallback-Logik anzuwenden.Nützliche Fallback-Problemumgehungen sind:
HTML-
<meta>
TagWenn Ihre Anwendung strukturell schwer zu reparieren ist, können Sie auf einfache (aber etwas unprofessionelle) Weise, um Weiterleitungen zuzulassen, ein HTML-
<meta>
Tag einfügen. Eine Weiterleitung kann erreicht werden mit:Oder mit kurzer Verzögerung:
Dies führt zu ungültigem HTML, wenn es nach dem
<head>
Abschnitt verwendet wird. Die meisten Browser akzeptieren es immer noch.JavaScript-Umleitung
Alternativ kann eine JavaScript-Umleitung für Seitenumleitungen verwendet werden:
Dies ist häufig HTML-kompatibler als die
<meta>
Problemumgehung, erfordert jedoch JavaScript-fähige Clients.Beide Ansätze machen jedoch akzeptable Fallbacks, wenn echte HTTP-Header () -Aufrufe fehlschlagen. Idealerweise kombinieren Sie dies immer mit einer benutzerfreundlichen Nachricht und einem anklickbaren Link als letzten Ausweg. (Welches ist zum Beispiel das, was der http_redirect () PECL-Erweiterung tut.)
Warum
setcookie()
undsession_start()
sind auch betroffenBeide
setcookie()
undsession_start()
müssen eine sendenSet-Cookie:
HTTP-Header . Es gelten daher die gleichen Bedingungen, und für vorzeitige Ausgabesituationen werden ähnliche Fehlermeldungen generiert.(Natürlich sind sie außerdem von deaktivierten Cookies im Browser oder sogar von Proxy-Problemen betroffen. Die Sitzungsfunktionalität hängt natürlich auch vom freien Speicherplatz und anderen php.ini-Einstellungen usw. ab.)
Weitere Links
quelle
?>
vom Ende einer PHP-Datei ist normalerweise eine gute Vorgehensweise, um diese Fehler ebenfalls zu minimieren. Unerwünschte Leerzeichen treten am Ende von Dateien nicht auf, und Sie können der Antwort später noch Header hinzufügen. Dies ist auch praktisch, wenn Sie die Ausgabepufferung verwenden und keine zusätzlichen unerwünschten Leerzeichen am Ende der von den enthaltenen Dateien generierten Teile sehen möchten.Diese Fehlermeldung wird ausgelöst, wenn etwas gesendet wird, bevor Sie HTTP-Header (mit
setcookie
oderheader
) senden . Häufige Gründe für die Ausgabe vor den HTTP-Headern sind:Versehentliches Leerzeichen, häufig am Anfang oder Ende von Dateien, wie folgt:
Um dies zu vermeiden, lassen Sie einfach das Schließen weg
?>
- es ist sowieso nicht erforderlich.3F 3C
. Sie können die Stückliste sicher vom Dateianfang entfernenEF BB BF
.echo
,printf
,readfile
,passthru
, Code vor<?
usw.display_errors
Eigenschaft php.ini festgelegt ist. Anstatt bei einem Programmiererfehler abzustürzen, behebt PHP den Fehler stillschweigend und gibt eine Warnung aus. Während Sie die Konfigurationendisplay_errors
oder error_reporting ändern können , sollten Sie das Problem lieber beheben.Häufige Gründe sind Zugriffe auf undefinierte Elemente eines Arrays (z. B.
$_POST['input']
ohne Verwendungempty
oderisset
zum Testen, ob die Eingabe festgelegt ist) oder die Verwendung einer undefinierten Konstante anstelle eines Zeichenfolgenliteral (wie in$_POST[input]
, beachten Sie die fehlenden Anführungszeichen).Durch Aktivieren der Ausgabepufferung sollte das Problem behoben werden. Alle Ausgaben nach dem Aufruf von werden
ob_start
im Speicher gepuffert, bis Sie den Puffer freigeben, zob_end_flush
. B. mit .Während die Ausgabepufferung die Probleme vermeidet, sollten Sie wirklich feststellen, warum Ihre Anwendung einen HTTP-Body vor dem HTTP-Header ausgibt. Das wäre so, als würde man einen Anruf entgegennehmen und Ihren Tag und das Wetter besprechen, bevor Sie dem Anrufer mitteilen, dass er die falsche Nummer hat.
quelle
Ich habe diesen Fehler schon oft erhalten, und ich bin sicher, dass alle PHP-Programmierer diesen Fehler mindestens einmal zuvor erhalten haben.
Mögliche Lösung 1
Dieser Fehler wurde möglicherweise durch Leerzeichen vor dem Start der Datei oder nach dem Ende der Datei verursacht. Diese Leerzeichen sollten nicht hier sein.
ex) HIER SOLLTEN KEINE LEEREN RAUME SEIN
Überprüfen Sie alle Dateien, die der Datei zugeordnet sind, die diesen Fehler verursacht.
Hinweis: Manchmal fügen EDITOR (IDE) wie gedit (ein Standard-Linux-Editor) eine leere Zeile zur Sicherungsdatei hinzu. Dies sollte nicht passieren. Wenn Sie Linux verwenden. Sie können den VI-Editor verwenden, um Leerzeichen / Zeilen nach?> am Ende der Seite zu entfernen.
Mögliche Lösung 2: Wenn dies nicht der Fall ist, verwenden Sie ob_start, um die Pufferung auszugeben:
Dadurch wird die Ausgabepufferung aktiviert und Ihre Header werden erstellt, nachdem die Seite gepuffert wurde.
quelle
ob_start()
versteckt nur das Problem; Verwenden Sie es nicht, um dieses spezielle Problem zu lösen.ob_start()
, was soll ich dann tun, um dieses Problem zu lösen:Headers already sent
ob_start()
nicht „verstecken“ das Problem, es löst das Problem.Anstelle der folgenden Zeile
schreiben
oder
Es wird definitiv Ihr Problem lösen. Ich hatte das gleiche Problem, aber ich habe es gelöst, indem ich die Position des Headers wie oben beschrieben geschrieben habe.
quelle
Sie machen
vor dem Setzen der Cookies, was nicht erlaubt ist. Sie können keine Ausgabe vor den Headern senden, nicht einmal eine leere Zeile.
quelle
Es liegt an dieser Zeile:
Sie sollten vor dem Senden der Header nichts drucken / wiedergeben .
quelle
ALLGEMEINE PROBLEME:
(kopiert von: Quelle )
====================
1)
echo..
Vor demheader(.......);
Befehl sollte keine Ausgabe (dh oder HTML-Code) erfolgen .2) Entfernen Sie Leerzeichen (oder Zeilenumbrüche ) vor
<?php
und nach?>
Tags.3) GOLDENE REGEL! - Überprüfen Sie, ob diese PHP-Datei (und auch, wenn Sie
include
andere Dateien haben) UTF8 ohne Stücklistencodierung (und nicht nur UTF-8 ) hat. Das ist in vielen Fällen ein Problem (weil die UTF8- codierte Datei am Anfang der PHP-Datei etwas Besonderes hat, das Ihr Texteditor nicht anzeigt) !!!!!!!!!!!4) Nachdem
header(...);
Sie verwenden müssenexit;
5) Verwenden Sie immer die Referenz 301 oder 302:
6) Aktivieren Sie die Fehlerberichterstattung und suchen Sie den Fehler. Ihr Fehler kann durch eine Funktion verursacht werden, die nicht funktioniert. Wenn Sie die Fehlerberichterstattung aktivieren, sollten Sie immer zuerst den häufigsten Fehler beheben. Beispielsweise könnte es sein: "Warnung: date_default_timezone_get (): Es ist nicht sicher, sich auf die Zeitzoneneinstellungen des Systems zu verlassen." - dann weiter unten sehen Sie möglicherweise den Fehler "Header nicht gesendet". Laden Sie Ihre Seite erneut, nachdem Sie den obersten (1.) Fehler behoben haben. Wenn Sie immer noch Fehler haben, beheben Sie erneut den obersten Fehler.
7) Wenn keiner der oben genannten Punkte hilft, verwenden Sie die JAVSCRIPT-Umleitung (jedoch eine stark nicht empfohlene Methode). Dies kann in benutzerdefinierten Fällen die letzte Chance sein ...:
quelle
301
oder302
wichtig?Ein einfacher Tipp: Ein einfaches Leerzeichen (oder ein unsichtbares Sonderzeichen) in Ihrem Skript direkt vor dem ersten
<?php
Tag kann dies verursachen! Besonders wenn Sie in einem Team arbeiten und jemand eine "schwache" IDE verwendet oder mit seltsamen Texteditoren in den Dateien herumgespielt hat.Ich habe diese Dinge gesehen;)
quelle
Eine andere schlechte Praxis kann dieses Problem hervorrufen, das noch nicht angegeben ist.
Siehe dieses Code-Snippet:
Die Dinge sind in Ordnung, oder?
Was ist, wenn "a_important_file.php" dies ist:
Das wird nicht funktionieren? Warum? Weil bereits eine neue Zeile generiert wird.
Obwohl dies kein alltägliches Szenario ist, was ist, wenn Sie ein MVC-Framework verwenden, das viele Dateien lädt, bevor Sie Dinge an Ihren Controller übergeben? Dies ist kein ungewöhnliches Szenario. Bereite dich darauf vor.
Aus PSR-2 2.2:
Unix LF (linefeed) line ending
.single blank line
.omitted
aus Dateien stammen, die enthaltenonly php
Glauben Sie mir, das Befolgen dieser Standards kann Ihnen verdammt viele Stunden Ihres Lebens ersparen :)
quelle
?>
Tag auf keinen Fall in eine DateiCR LF
(typischen Windows-Zeilenende). Ich löse es, indem ich die Originaldatei von Wordpress Repo herunterlade, dieLF
stattdessen (Linux-Zeilenende) hat,CR LF
und ich habe meine Funktion auch in die Datei functions.php des Themas verschoben. Basierend auf: bit.ly/1Gh6mzN?>
<?php
, Entfernen und Hinzufügen einer einzelnen Leerzeile, Hinzufügen und Weglassen des schließenden Tags?>
. In Windows + Wamp funktionieren alle diese Kombinationen einwandfrei. Wierd ...Manchmal , wenn der Entwickler Prozess sowohl WIN Arbeitsplätze und Linux - Systemen hat (Hosting) und in dem Code , den Sie keine Ausgabe , bevor die betreffende Zeile sehen Sie, könnte es die Formatierung der Datei und den Mangel an sein Unix LF (Zeilenvorschub) Zeilenende .
Um dies schnell zu beheben, benennen wir die Datei normalerweise um und erstellen auf dem LINUX-System eine neue Datei anstelle der umbenannten und kopieren dann den Inhalt in diese. Oft löst dies das Problem, da einige der Dateien, die in WIN erstellt wurden, nachdem sie auf das Hosting verschoben wurden, dieses Problem verursachen.
Dieser Fix ist ein einfacher Fix für Websites, die wir per FTP verwalten, und kann unseren neuen Teammitgliedern manchmal Zeit sparen.
quelle
Im Allgemeinen tritt dieser Fehler auf, wenn wir nach dem Echo oder Drucken einen Header senden. Wenn dieser Fehler auf einer bestimmten Seite auftritt, stellen Sie sicher, dass auf dieser Seite nichts wiedergegeben wird, bevor Sie aufrufen
start_session()
.Beispiel für einen unvorhersehbaren Fehler:
Noch ein Beispiel:
Fazit: Geben Sie vor dem Aufruf kein Zeichen aus
session_start()
oderheader()
funktionieren Sie nicht einmal als Leerzeichen oder neue Zeilequelle