Frage Wie behebt man den Fehler "Header senten sent" in PHP?


Wenn ich mein Skript ausführe, erhalte ich mehrere Fehler:

Warnung: Header-Informationen können nicht geändert werden - Header, die bereits vonAusgabe gestartet um /some/file.php:12) im /some/file.php auf Linie 23

Die in den Fehlermeldungen erwähnten Zeilen enthalten header() und setcookie() Anrufe.

Was könnte der Grund dafür sein? Und wie man es repariert?


836
2017-11-06 17:45


Ursprung


Antworten:


Keine Ausgabe vor dem Senden der Header!

Funktionen, die HTTP-Header senden / ändern, müssen aufgerufen werden bevor irgendeine Ausgabe gemacht wird. Zusammenfassung ⇊ Andernfalls schlägt der Aufruf fehl:

Warnung: Kopfzeileninformationen können nicht geändert werden - bereits gesendete Kopfzeilen (die Ausgabe wurde bei gestartet Skript: Zeile)

Einige Funktionen zum Ändern des HTTP-Headers sind:

Ausgabe kann sein:

  • Unbeabsichtigt:

  • Absichtlich:

    • print, echo und andere Funktionen, die eine Ausgabe erzeugen
    • Roh <html> Abschnitte vorher <?php Code.

Warum passiert das?

Um zu verstehen, warum Header vor der Ausgabe gesendet werden müssen, ist es notwendig ein typisches betrachten HTTP Antwort. PHP-Skripte erzeugen hauptsächlich HTML-Inhalte, aber auch a Set von HTTP / CGI-Headern zum Webserver:

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

<html><head><title>PHP page output page</title></head>
<body><h1>Content</h1> <p>Some more output follows...</p>
and <a href="/"> <img src=internal-icon-delayed> </a>

Die Seite / Ausgabe immer folgt die Header. PHP muss bestehen Kopfzeilen an den Webserver zuerst. Es kann das nur einmal tun. Nach dem doppelten Zeilenwechsel kann sie nicht mehr geändert werden.

Wenn PHP die erste Ausgabe empfängt (print, echo, <html>) es wird spülen alle gesammelten Header. Danach kann es die gesamte Ausgabe senden es will. Aber das Senden weiterer HTTP-Header ist dann unmöglich.

Wie können Sie herausfinden, wo die vorzeitige Ausgabe aufgetreten ist?

Das header() Warnung enthält alle relevanten Informationen zu Lokalisieren Sie die Ursache des Problems:

Warnung: Header-Informationen können nicht geändert werden - Header, die bereits gesendet wurden    (Ausgang gestartet um / www / usr2345 / htdocs /auth.php: 52) im   /www/usr2345/htdocs/index.php in Zeile 100

Hier bezieht sich "Zeile 100" auf das Skript, in dem der header()  Aufruf gescheitert.

Das "Ausgabe begann um"Anmerkung in den Klammern ist signifikanter. Es bezeichnet die Quelle der vorherigen Ausgabe. In diesem Beispiel ist es auth.php und Linie 52. Dort mussten Sie nach vorzeitiger Ausgabe Ausschau halten.

Typische Ursachen:

  1. Drucken, Echo

    Absichtliche Ausgabe von print und echo Aussagen werden beendet die Möglichkeit, HTTP-Header zu senden. Der Anwendungsfluss muss umstrukturiert werden, um das zu vermeiden. Benutzen Funktionen und Templating-Schemata. Dafür sorgen header() Anrufe auftreten Vor Mitteilungen sind ausgeschrieben.

    Funktionen, die Ausgabe erzeugen, umfassen

    • 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.

  2. Raw-HTML-Bereiche

    Unparsed HTML-Abschnitte in a .php Datei werden auch direkt ausgegeben. Skriptbedingungen, die ein. Auslösen header() Anruf muss notiert werden Vor irgendein roh <html> Blöcke.

    <!DOCTYPE html>
    <?php
        // Too late for headers already.
    

    Verwenden Sie ein Template-Schema, um die Verarbeitung von der Ausgangslogik zu trennen.

    • Platzieren Sie Formularverarbeitungscode auf Skripts.
    • Verwenden Sie temporäre String-Variablen, um Nachrichten zu verzögern.
    • Die tatsächliche Ausgabelogik und die gemischte HTML-Ausgabe sollten zuletzt folgen.

  3. Whitespace vorher <?php für "script.php Linie 1"Warnungen

    Wenn sich die Warnung auf die Ausgabe in der Zeile bezieht 1dann ist es meistens führend Leerzeichen, Text oder HTML vor der Eröffnung <?php Zeichen.

     <?php
    # There's a SINGLE space/newline before <? - Which already seals it.
    

    Ähnlich kann es bei angehängten Skripten oder Skriptabschnitten vorkommen:

    ?>
    
    <?php
    

    PHP isst tatsächlich ein Single Zeilenumbruch nach geschlossenen Tags. Aber es wird nicht Kompensieren Sie mehrere Zeilenumbrüche oder Tabs oder Leerzeichen, die in solche Lücken verschoben wurden.

  4. UTF-8 Stückliste

    Zeilenumbrüche und Leerzeichen können ein Problem sein. Aber es gibt auch "unsichtbare" Zeichenfolgen, die dies verursachen können. Am bekanntesten ist die UTF-8 Stückliste (Byte-Order-Mark) was von den meisten Texteditoren nicht angezeigt wird. Es ist die Bytefolge EF BB BF, welche ist optional und redundant für UTF-8-kodierte Dokumente. PHP muss jedoch behandeln es als rohe Ausgabe. Es kann als die Zeichen angezeigt werden  in der Ausgabe (wenn der Client interpretiert das Dokument als Latin-1) oder ähnlichen "Müll".

    Insbesondere grafische Editoren und Java-basierte IDEs sind sich dessen nicht bewusst Gegenwart. Sie visualisieren es nicht (nach dem Unicode-Standard). Die meisten Programmierer und Konsolen-Editoren machen jedoch:

    joes editor showing UTF-8 BOM placeholder, and MC editor a dot

    Da ist es leicht, das Problem früh zu erkennen. Andere Redakteure können identifizieren seine Anwesenheit in einem Datei- / Einstellungsmenü (Notepad ++ unter Windows kann identifizieren und behebe das Problem), Eine weitere Möglichkeit, die Präsenz der Stücklisten zu überprüfen, besteht darin, auf eine Hexeditor. On * nix Systeme hexdump ist normalerweise verfügbar, wenn nicht eine grafische Variante, die das Auditing dieser und anderer Probleme vereinfacht:

    beav hexeditor showing utf-8 bom

    Eine einfache Lösung besteht darin, den Texteditor so einzustellen, dass Dateien als "UTF-8 (keine Stückliste)" gespeichert werden. oder eine ähnliche Nomenklatur. Oft greifen Neulinge sonst auf Neues zurück Dateien und kopieren Sie einfach den vorherigen Code wieder hinein.

    Korrekturdienstprogramme

    Es gibt auch automatisierte Tools zum Prüfen und Neuschreiben von Textdateien (sed/awk oder recode). Speziell für PHP gibt es das phptags Tag-Ordnung. Es umschreibt sowohl offene als auch offene Tags in lange und kurze Formen, aber auch einfach behebt führende und nachfolgende Whitespace-, Unicode- und UTF-x-BOM-Probleme:

    phptags  --whitespace  *.php
    

    Es ist sinnvoll, es für ein ganzes Include- oder Projektverzeichnis zu verwenden.

  5. Whitespace nach ?>

    Wenn die Fehlerquelle als hinter der Schließen ?> Dann wurden einige Leerzeichen oder Rohtext ausgeschrieben. Der PHP-Endmarker beendet die Skriptausführung nicht Punkt. Irgendwelche Text- / Leerzeichen-Zeichen werden danach als Seiteninhalt ausgeschrieben immer noch.

    Es wird allgemein empfohlen, insbesondere für Neueinsteiger, dass sie hinterherhinken ?> PHP Schließe Tags sollten weggelassen werden. Dies meidet ein kleiner Teil dieser Fälle. (Ziemlich häufig include()d Skripte sind der Schuldige.)

  6. Fehlerquelle als "Unbekannt in Zeile 0"

    Es ist normalerweise eine PHP-Erweiterung oder php.ini Einstellung, wenn keine Fehlerquelle ist konkretisiert.

    • Es ist gelegentlich der gzip Stream-Encoding-Einstellung oder der ob_gzhandler.
    • Es könnte aber auch beliebig doppelt geladen sein extension= Modul Erzeugen einer impliziten PHP-Start- / Warnmeldung

  7. Vorangegangene Fehlermeldungen

    Wenn eine andere PHP-Anweisung oder ein anderer Ausdruck eine Warnmeldung verursacht oder wenn die Notiz ausgedruckt wird, gilt das auch als vorzeitige Ausgabe.

    In diesem Fall müssen Sie den Fehler vermeiden, verzögern die Ausführung der Anweisung oder unterdrücken die Nachricht mit z.B. isset() oder @() - wenn das Debuggen später nicht behindert wird.

Keine Fehlermeldung

Wenn Sie haben error_reporting oder display_errors deaktiviert per php.ini, dann wird keine Warnung angezeigt. Aber das Ignorieren von Fehlern wird das Problem nicht lösen Weg. Kopfzeilen können nach vorzeitiger Ausgabe noch nicht gesendet werden.

Also wann header("Location: ...") Redirects im Stillen scheitern es ist sehr ratsam, nach Warnungen zu suchen. Erneut mit zwei einfachen Befehlen reaktivieren über dem Aufrufskript:

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

Oder set_error_handler("var_dump"); wenn alle Stricke reißen.

Apropos Redirect Header, sollten Sie oft ein Idiom wie verwenden dies für die letzten Codepfade:

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

Vorzugsweise sogar eine Dienstprogrammfunktion, die eine Benutzermeldung ausgibt im Falle von header() Fehler.

Pufferung der Ausgabe als Workaround

PHPs Pufferung der Ausgabe ist eine Problemumgehung, um dieses Problem zu beheben. Es funktioniert oft zuverlässig, sollte es aber nicht Ersatz für eine ordnungsgemäße Anwendungsstrukturierung und Trennung der Ausgabe von der Kontrolle Logik. Sein tatsächlicher Zweck ist die Minimierung von Chunked-Übertragungen an den Webserver.

  1. Das output_buffering= Einstellung kann aber helfen. Konfigurieren Sie es in der php.ini oder über .htaccess oder auch .user.ini auf moderne FPM / FastCGI-Setups.
    Wenn PHP aktiviert wird, kann PHP die Ausgabe puffern, anstatt sie an den Webserver zu übergeben sofort. PHP kann somit HTTP-Header aggregieren.

  2. Es kann ebenfalls mit einem Anruf angerufen werden ob_start(); über dem Aufrufskript. Was jedoch aus mehreren Gründen weniger zuverlässig ist:

    • Selbst wenn <?php ob_start(); ?> Startet das erste Skript, Whitespace oder a BOM könnte vorher gemischt werden, macht es unwirksam.

    • Es kann Leerzeichen für die HTML-Ausgabe verbergen. Aber sobald die Anwendung Logik versucht, binären Inhalt zu senden (z. B. ein generiertes Bild), die gepufferte externe Ausgabe wird zu einem Problem. (Notwendig ob_clean() als weitere Problemumgehung.)

    • Der Puffer ist in seiner Größe begrenzt und kann leicht überschritten werden, wenn er auf die Standardwerte zurückgesetzt wird. Und das ist auch kein seltenes Ereignis, schwer aufzuspüren wenn es passiert.

Beide Ansätze können daher unzuverlässig werden - insbesondere beim Wechsel zwischen Entwicklungs-Setups und / oder Produktions-Server. Deshalb ist die Ausgabepufferung weithin nur eine Krücke / streng als Workaround.

Siehe auch die grundlegendes Verwendungsbeispiel im Handbuch und für weitere Vor- und Nachteile:

Aber es hat auf dem anderen Server funktioniert !?

Wenn Sie die Header-Warnung vorher nicht erhalten haben, dann Pufferung der Ausgabe  php.ini Einstellung  hat sich verändert. Es ist wahrscheinlich auf dem aktuellen / neuen Server nicht konfiguriert.

Überprüfung mit headers_sent()

Sie können immer verwenden headers_sent() zu prüfen, ob es ist immer noch möglich ... Header zu senden. Das ist nützlich, um bedingt zu drucken eine Info oder wenden Sie eine andere Fallback-Logik an.

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

Nützliche Fallback-Problemumgehungen sind:

  • HTML <meta> Etikett

    Wenn Ihre Anwendung strukturell schwer zu reparieren ist, dann ein einfaches (aber etwas unprofessionell) Weg, Redirects zu erlauben, injiziert einen HTML <meta> Etikett. Eine Umleitung kann erreicht werden mit:

     <meta http-equiv="Location" content="http://example.com/">
    

    Oder mit einer kurzen Verzögerung:

     <meta http-equiv="Refresh" content="2; url=../target.html">
    

    Dies führt zu ungültigem HTML, wenn es nach dem verwendet wird <head> Sektion. Die meisten Browser akzeptieren es immer noch.

  • JavaScript-Weiterleitung

    Als Alternative a JavaScript-Weiterleitung kann für Seitenweiterleitungen verwendet werden:

     <script> location.replace("target.html"); </script>
    

    Dies ist zwar oft HTML-kompatibler als das <meta> Problemumgehung, Es beruht auf JavaScript-fähigen Clients.

Beide Ansätze machen jedoch akzeptable Fallbacks bei echtem HTTP-Header () Anrufe schlagen fehl. Im Idealfall würden Sie dies immer mit einer benutzerfreundlichen Nachricht kombinieren und anklickbarer Link als letztes Mittel. (Was zum Beispiel ist das, was http_redirect () PECL-Erweiterung tut.)

Warum setcookie() und session_start() sind ebenfalls betroffen

Beide setcookie() und session_start() muss senden a Set-Cookie: HTTP-Header Daher gelten die gleichen Bedingungen und ähnliche Fehlermeldungen werden generiert für vorzeitige Ausgabesituationen.

(Natürlich sind sie weiterhin von deaktivierten Cookies im Browser betroffen, oder sogar Proxy-Probleme. Die Sitzungsfunktionalität hängt natürlich auch von freien ab Speicherplatz und andere php.ini Einstellungen, etc.)

Weitere Links


2640
2017-11-06 17:44



Diese Fehlermeldung wird ausgelöst, wenn etwas wird gesendet, bevor Sie HTTP - Header senden (mit setcookie oder header). Häufige Gründe für die Ausgabe von etwas vor den HTTP-Headern sind:

  • Zufällige Leerzeichen, oft am Anfang oder am Ende von Dateien, so:

     <?php
    // Note the space before "<?php"
    ?>
    

Um dies zu vermeiden, lassen Sie das Schließen einfach weg ?> - Es ist sowieso nicht erforderlich.

  • Byte-Bestellzeichen am Anfang einer PHP-Datei. Untersuchen Sie Ihre PHP-Dateien mit einem Hex-Editor, um herauszufinden, ob dies der Fall ist. Sie sollten mit den Bytes beginnen 3F 3C. Sie können die Stückliste sicher entfernen EF BB BF von Anfang an Dateien.
  • Explizite Ausgabe, z. B. Aufrufe an echo, printf, readfile, passthru, Code vorher <? etc.
  • Eine Warnung, die von PHP ausgegeben wird, wenn der display_errors Die php.ini-Eigenschaft ist festgelegt. Anstatt auf einen Programmierfehler zu stürzen, behebt php den Fehler und gibt eine Warnung aus. Während Sie die ändern können display_errors oder Fehler melden Konfigurationen sollten Sie das Problem eher beheben.
    Häufige Gründe sind Zugriffe auf undefinierte Elemente eines Arrays (wie z $_POST['input'] ohne zu benutzen empty oder isset um zu testen, ob die Eingabe gesetzt ist) oder eine undefinierte Konstante anstelle eines String - Literals (wie in $_POST[input], notiere die fehlenden Zitate).

Einschalten Pufferung der Ausgabe sollte das Problem verschwinden lassen; Alle Ausgaben nach dem Anruf an ob_start wird im Speicher gepuffert, bis Sie den Puffer freigeben, z. mit ob_end_flush.

Während die Pufferung der Ausgabe jedoch die Probleme vermeidet, sollten Sie wirklich herausfinden, warum Ihre Anwendung vor dem HTTP-Header einen HTTP-Body ausgibt. Das wäre, als würdest du einen Anruf tätigen und über deinen Tag und das Wetter sprechen, bevor du dem Anrufer mitteilst, dass er die falsche Nummer hat.


178
2017-08-01 06:43



Ich habe diesen Fehler viele Male vorher bekommen. Und ich bin sicher, dass alle PHP-Programmierer mindestens einmal diesen Fehler bekommen haben. Um diesen Fehler zu beheben, können Sie die Lösungslösung gemäß Ihrer Problemstufe lösen:

Mögliche Lösung 1:

Möglicherweise haben Sie Leerzeichen hinterlassen Vor oder nach (am Ende der Datei nach?>) d.h.

THERE SHOULD BE NO BLANK SPACES HERE
<?php  

   echo "your code here";

?>
DO CHECK FOR BLANK SPACES HERE AS WELL; THIS LINE (blank line) SHOULD NOT EXIST.

Die meiste Zeit sollte dies Ihr Problem lösen. Überprüfen Sie alle Dateien, die mit der Datei verbunden sind require.

Hinweis:  Manchmal EDITOR (IDE) wie gedit (ein Standard-Linux-Editor) fügen Sie eine leere Zeile bei Speichern Datei. 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.

Wenn das nicht Ihr Fall ist, dann können Sie verwenden ob_start für die Ausgabepufferung wie folgt:

Mögliche Lösung 2:

<?php
  ob_start();

  // code 

 ob_end_flush();
?> 

101
2018-03-24 12:54



Anstatt der unteren Zeile

//header("Location:".ADMIN_URL."/index.php");

schreiben

echo("<script>location.href = '".ADMIN_URL."/index.php?msg=$msg';</script>");

oder

?><script><?php echo("location.href = '".ADMIN_URL."/index.php?msg=$msg';");?></script><?php

Es wird definitiv dein Problem lösen. Ich hatte das gleiche Problem, aber ich löste das Schreiben der Header-Position auf die obige Weise.


73
2017-11-06 17:45



Sie machen

printf ("Hi %s,</br />", $name);

vor dem Setzen der Cookies, was nicht erlaubt ist. Sie können keine Ausgabe vor den Headern senden, nicht einmal eine leere Zeile.


38
2017-11-06 17:45



Es ist wegen dieser Linie:

printf ("Hi %s,</br />", $name);

Du solltest nicht Drucken / Echo alles vor dem Senden der Header.


29
2018-05-16 20:37



Ein einfacher Tipp: Ein einfacher Platz (oder unsichtbarer Sonderzeichen) in deinem Skript, direkt vor dem allerersten <?php Tag, kann dies verursachen! Vor allem, wenn Sie in einem Team arbeiten und jemand eine "schwache" IDE verwendet oder sich in den Dateien mit seltsamen Texteditoren herumärgert.

Ich habe diese Dinge gesehen;)


25
2017-11-08 01:29