831 Stimmen

Wie behebt man den Fehler "Headers already sent" in PHP

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

Warnung: Cannot modify header information - headers already sent by ( Die Ausgabe begann bei /some/file.php:12 ) in /some/file.php auf Zeile 23

Die in den Fehlermeldungen genannten Zeilen enthalten header() y setcookie() Anrufe.

Was könnte der Grund dafür sein? Und wie lässt es sich beheben?

3294voto

mario Punkte 141130

Keine Ausgabe vor dem Senden von Kopfzeilen!

Funktionen zum Senden/Ändern von HTTP-Headern müssen aufgerufen werden bevor irgendeine Ausgabe gemacht wird . <a href="https://stackoverflow.com/a/8028979/345031"><strong>summary </strong></a> Andernfalls schlägt der Aufruf fehl:

Warnung: Cannot modify header information - headers already sent (Ausgabe begann bei Skript:Zeile )

Einige Funktionen, die den HTTP-Header verändern, sind:

Die Ausgabe kann sein:

  • Unbeabsichtigt:

    • Whitespace vor <?php oder nach ?>
    • El UTF-8 Byte Order Mark speziell
    • Frühere Fehlermeldungen oder Hinweise
  • Absichtlich:

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

Wie kommt es dazu?

Um zu verstehen, warum Kopfzeilen vor der Ausgabe gesendet werden müssen, ist es notwendig einen Blick auf eine typische HTTP Antwort. PHP-Skripte erzeugen hauptsächlich HTML-Inhalte, übergeben aber auch eine eine Reihe von HTTP/CGI-Headern an den 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="http://stackoverflow.com/"> <img src=internal-icon-delayed> </a>

Die Seite/Ausgabe ist immer folgt die Kopfzeilen. PHP muss die Header zuerst an den Webserver weitergeben. Das kann es nur einmal tun. Nach dem doppelten Zeilenumbruch kann es sie nicht mehr ändern.

Wenn PHP die erste Ausgabe erhält ( print , echo , <html> ) wird es Spülen alle gesammelten Kopfzeilen. Danach kann er alle gewünschten Ausgaben die er will. Aber das Senden weiterer HTTP-Header ist dann unmöglich.

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

El header() Warnung enthält alle relevanten Informationen, um die Ursache des Problems zu finden:

Warnung: Cannot modify header information - headers already sent by (die Ausgabe begann bei /www/usr2345/htdocs/ auth.php:52 ) in /www/usr2345/htdocs/index.php in Zeile 100

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

Die " Die Ausgabe begann bei "Der Hinweis in der Klammer ist von größerer Bedeutung. Er bezeichnet die Quelle der vorherigen Ausgabe. In diesem Beispiel ist es auth.php y Zeile 52 . Das ist der Punkt, an dem man nach vorzeitigem Output suchen muss.

Typische Ursachen:

  1. Drucken, Echo

    Beabsichtigte Ausgabe von print y echo Anweisungen wird die Möglichkeit, HTTP-Header zu senden, beendet. Um dies zu vermeiden, muss der Anwendungsablauf umstrukturiert werden. verwenden funciones und Schemata. Sicherstellen header() Anrufe erfolgen vor 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.

  2. Rohe HTML-Bereiche

    Unparsed HTML-Abschnitte in einer .php Datei werden ebenfalls direkt ausgegeben. Skriptbedingungen, die eine header() Anruf muss vermerkt werden vor cualquier roh <html> Blöcke.

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

    Verwenden Sie ein Schablonenschema, um die Verarbeitung von der Ausgabelogik zu trennen.

    • Platzieren Sie den Code für die Formularverarbeitung in Skripten.
    • Verwenden Sie temporäre String-Variablen, um Nachrichten zu verschieben.
    • Die eigentliche Ausgabelogik und die eingemischte HTML-Ausgabe sollten zuletzt folgen.
  3. Whitespace vor <?php für "script.php Zeile 1 " Warnungen

    Wenn sich die Warnung auf die Inline-Ausgabe bezieht 1 dann ist es meistens führend Leerzeichen , Text oder HTML vor der Öffnung <?php Token.

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

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

    ?>
    
    <?php

    PHP frisst tatsächlich eine einzeln Zeilenumbruch nach Close-Tags. Aber es wird nicht mehrere Zeilenumbrüche oder Tabulatoren oder Leerzeichen, die in solche Lücken verschoben werden, nicht kompensieren.

  4. UTF-8 BOM

    Zeilenumbrüche und Leerzeichen allein können ein Problem darstellen. Aber es gibt auch "unsichtbare" Zeichenfolgen, die dies verursachen können. Am bekanntesten ist die UTF-8 BOM (Byte-Order-Marke) die von den meisten Texteditoren nicht angezeigt wird. Es handelt sich um die Bytefolge EF BB BF die bei UTF-8-kodierten Dokumenten optional und überflüssig ist. PHP muss sie jedoch als Rohausgabe behandeln. Sie kann als die folgenden Zeichen angezeigt werden in der Ausgabe (wenn der Client das Dokument als Latin-1 interpretiert) oder ähnlichen "Müll".

    Vor allem grafische Editoren und Java-basierte IDEs kennen es nicht Präsenz. Sie zeigen es nicht an (was durch den Unicode-Standard vorgeschrieben ist). Die meisten Programmier- und Konsoleneditoren hingegen schon:

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

    Dort ist es einfach, das Problem frühzeitig zu erkennen. Andere Editoren erkennen möglicherweise das Vorhandensein in einem Datei-/Einstellungsmenü (Notepad++ unter Windows kann es erkennen und das Problem zu beheben ), Eine weitere Möglichkeit, das Vorhandensein von Stücklisten zu prüfen, ist der Rückgriff auf eine hexeditor . Auf *nix-Systemen hexdump ist normalerweise verfügbar, wenn nicht sogar eine grafische Variante, die die Prüfung dieser und anderer Fragen vereinfacht:

    beav hexeditor showing utf-8 bom

    Eine einfache Lösung besteht darin, den Texteditor so einzustellen, dass Dateien als "UTF-8 (no BOM)" gespeichert werden. oder einer ähnlichen Nomenklatur zu speichern. Andernfalls erstellen Neulinge oft neue Dateien und fügen den vorherigen Code einfach per Copy & Paste wieder ein.

    Berichtigung Dienstprogramme

    Es gibt auch automatisierte Tools, um Textdateien zu untersuchen und neu zu schreiben ( sed / awk ou recode ). Speziell für PHP gibt es die phptags Tag ordentlicher . Es schreibt Close- und Open-Tags in Lang- und Kurzformen um, behebt aber auch leicht behebt führende und nachgestellte Leerzeichen, Unicode- und UTF-x-BOM-Probleme:

    phptags  --whitespace  *.php

    Es ist sicher, auf ein ganzes Include- oder Projektverzeichnis anzuwenden.

  5. Whitespace nach ?>

    Wenn die Fehlerquelle als hinter dem Schließen ?> dann ist dies der Ort, an dem Leerraum oder der Rohtext herausgeschrieben wurde. Die PHP-Endmarkierung beendet die Skriptausführung an dieser Stelle nicht. Jeder Text/jedes Leerzeichen danach wird als Seiteninhalt ausgegeben noch.

    Es wird allgemein empfohlen, insbesondere für Neueinsteiger, dass die ?> PHP close-Tags sollten weggelassen werden. Diese unterlässt ein kleiner Teil dieser Fälle. (Ziemlich häufig include()d Skripte sind der Übeltäter).

  6. Die Fehlerquelle wird als "Unbekannt in Zeile 0" angegeben.

    Normalerweise ist es eine PHP-Erweiterung oder eine php.ini-Einstellung, wenn keine Fehlerquelle konkretisiert ist.

    • Gelegentlich ist es die gzip Stream-Codierungseinstellung oder die ob_gzhandler .
    • Es könnte sich aber auch um jede doppelt geladene extension= Modul das eine implizite PHP-Start-/Warnmeldung erzeugt.
  7. Vorangegangene Fehlermeldungen

    Wenn eine andere PHP-Anweisung oder ein Ausdruck eine Warnmeldung oder Hinweis ausgibt, zählt dies ebenfalls als vorzeitige Ausgabe.

    In diesem Fall müssen Sie den Fehler beseitigen, die Ausführung der Anweisung verzögern oder die Meldung unterdrücken, z. B. mit isset() ou @() - wenn beides die spätere Fehlersuche nicht behindert.

Keine Fehlermeldung

Wenn Sie eine error_reporting ou display_errors deaktiviert pro php.ini , dann wird keine Warnung angezeigt. Aber das Ignorieren von Fehlern führt nicht dazu, dass das Problem verschwindet. verschwinden. Kopfzeilen können nach einer vorzeitigen Ausgabe immer noch nicht gesendet werden.

Wenn also header("Location: ...") Umleitungen stillschweigend scheitern, ist es sehr ratsam, auf Warnungen zu achten. Sie können mit zwei einfachen Befehlen wieder aktiviert werden oberhalb des Aufrufskripts:

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

Oder set_error_handler("var_dump"); wenn alles andere versagt.

Apropos Redirect-Header, Sie sollten oft eine Redewendung wie für endgültige Codepfade verwenden:

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

Vorzugsweise sogar eine Hilfsfunktion, die eine Benutzermeldung ausgibt im Falle von header() Ausfälle.

Ausgabepufferung als Abhilfe

PHPs Ausgangspufferung ist eine Abhilfemaßnahme, um dieses Problem zu beheben. Sie funktioniert oft zuverlässig, sollte aber nicht die richtige Strukturierung der Anwendung und die Trennung von Ausgabe und Steuerung logik. Ihr eigentlicher Zweck ist die Minimierung von Chunked-Transfers zum Webserver.

  1. El output_buffering= Einstellung kann dennoch helfen. Konfigurieren Sie sie in der php.ini oder über .htaccess oder sogar .user.ini auf modernen FPM/FastCGI-Konfigurationen.
    Wenn Sie diese Option aktivieren, kann PHP die Ausgabe puffern, anstatt sie sofort an den Webserver zu übergeben. PHP kann somit HTTP-Header aggregieren.

  2. Sie kann ebenfalls mit einem Aufruf zur ob_start(); auf dem Aufrufskript. Dies ist jedoch aus mehreren Gründen weniger zuverlässig:

    • Auch wenn <?php ob_start(); ?> beginnt das erste Skript, Leerzeichen oder ein BOM könnte vorher gemischt werden, und damit unwirksam machen .

    • Es kann Leerzeichen für die HTML-Ausgabe verbergen. Sobald jedoch die Anwendungslogik versucht, binäre Inhalte zu senden (z. B. ein generiertes Bild) wird die gepufferte fremde Ausgabe zum Problem. (Erforderlich ob_clean() als weitere Abhilfe).

    • Der Puffer ist in seiner Größe begrenzt und kann leicht überlaufen, wenn er auf die Standardeinstellungen zurückgesetzt wird. Und auch das ist kein seltenes Vorkommnis, schwer auffindbar wenn es passiert.

Beide Ansätze können daher unzuverlässig werden - vor allem beim Wechsel zwischen Entwicklungs-Setups und/oder Produktionsservern. Aus diesem Grund wird die Ausgabepufferung weithin nur als Krücke / reine Notlösung angesehen.

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

Aber auf dem anderen Server hat es funktioniert!?

Wenn Sie die Kopfzeilen-Warnung vorher nicht erhalten haben, dann ist die Ausgangspufferung php.ini-Einstellung hat sich geändert. Er ist wahrscheinlich auf dem aktuellen/neuen Server nicht konfiguriert.

Prüfen mit headers_sent()

Sie können jederzeit die headers_sent() zu prüfen, ob es immer noch möglich ist... Kopfzeilen zu senden. Das ist nützlich, um bedingte Info zu drucken oder andere Fallback-Logik anzuwenden.

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

Nützliche Behelfslösungen sind:

  • HTML <meta> Tag

    Wenn Ihre Anwendung strukturell schwer zu reparieren ist, dann ist eine einfache (aber eine einfache (aber etwas unprofessionelle) Möglichkeit, Weiterleitungen zuzulassen, die Einfügung eines HTML <meta> Tag. Eine Weiterleitung kann mit erreicht werden:

     <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 hinter dem <head> Abschnitt. Die meisten Browser akzeptieren sie noch.

  • JavaScript-Weiterleitung

    Als Alternative ein JavaScript-Weiterleitung kann für Seitenumleitungen verwendet werden:

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

    Dies ist zwar oft HTML-kompatibler als die <meta> Abhilfe, ist er auf JavaScript-fähige Clients angewiesen.

Beide Ansätze sind jedoch akzeptable Ausweichlösungen, wenn echte HTTP-Header() Aufrufe fehlschlagen. Idealerweise kombinieren Sie dies immer mit einer benutzerfreundlichen Meldung und anklickbaren Link als letzten Ausweg. (Das ist zum Beispiel das, was die http_redirect() PECL-Erweiterung).

Warum setcookie() y session_start() sind ebenfalls betroffen

Beide setcookie() y session_start() Sie müssen eine Set-Cookie: HTTP-Header. Es gelten daher die gleichen Bedingungen, und es werden ähnliche Fehlermeldungen erzeugt für vorzeitige Ausgabesituationen erzeugt.

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

Weitere Links

215voto

phihag Punkte 261131

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

  • Versehentlicher Leerraum, oft am Anfang oder Ende von Dateien, wie hier:

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

       Um dies zu vermeiden, lassen Sie einfach das Schlusswort weg ?> - es ist ohnehin nicht erforderlich.

  • Byte-Order-Marken am Anfang einer php-Datei. Untersuchen Sie Ihre php-Dateien mit einem Hex-Editor, um herauszufinden, ob das der Fall ist. Sie sollten mit den folgenden Bytes beginnen 3F 3C . Sie können die Stückliste sicher entfernen EF BB BF vom Beginn der Dateien an.
  • Explizite Ausgaben, wie z. B. Aufrufe von echo , printf , readfile , passthru , Code vor <? etc.
  • Eine Warnung, die von php ausgegeben wird, wenn die display_errors php.ini-Eigenschaft gesetzt ist. Anstatt aufgrund eines Programmierfehlers abzustürzen, behebt php den Fehler stillschweigend und gibt eine Warnung aus. Sie können zwar die display_errors ou fehler_berichterstattung Konfigurationen, sollten Sie lieber das Problem beheben.
    Häufige Gründe sind Zugriffe auf undefinierte Elemente eines Arrays (wie z.B. $_POST['input'] ohne Verwendung empty ou isset um zu prüfen, ob die Eingabe gesetzt ist), oder die Verwendung einer undefinierten Konstante anstelle eines String-Literales (wie in $_POST[input] (beachten Sie die fehlenden Anführungszeichen).

Einschalten Ausgangspufferung sollte das Problem verschwinden lassen; alle Ausgaben nach dem Aufruf von ob_start wird im Speicher zwischengespeichert, bis Sie den Puffer freigeben, z. B. mit ob_end_flush .

Auch wenn 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ürden Sie einen Telefonanruf entgegennehmen und Ihren Tag und das Wetter besprechen, bevor Sie dem Anrufer mitteilen, dass er sich verwählt hat.

134voto

Manish Shrivastava Punkte 27921

Ich habe diesen Fehler schon oft gehabt, und ich bin sicher, dass alle PHP-Programmierer diesen Fehler mindestens einmal hatten.

Mögliche Lösung 1

Dieser Fehler kann durch die Leerzeichen verursacht worden sein vor den Anfang der Datei oder nach Diese Leerzeichen sollten hier nicht vorhanden sein.

ex) HIER SOLLTEN KEINE LEERZEICHEN SEIN

   echo "your code here";

?>
THERE SHOULD BE NO BLANK SPACES HERE

Überprüfen Sie alle Dateien, die mit der Datei verbunden sind, die diesen Fehler verursacht.

Anmerkung: Manchmal fügen EDITOR(IDE) wie gedit (ein Standard-Linux-Editor) eine Leerzeile beim Speichern der Datei hinzu. Dies sollte nicht passieren. Wenn Sie Linux verwenden, können Sie 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, dann verwenden Sie ob_start zur Ausgabepufferung:

<?php
  ob_start();

  // code 

 ob_end_flush();
?> 

Dadurch wird die Ausgabepufferung aktiviert und Ihre Kopfzeilen werden nach der Pufferung der Seite erstellt.

101voto

Ipsita Rout Punkte 4495

Anstelle der folgenden 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

Das wird Ihr Problem definitiv lösen. Ich stand vor dem gleichen Problem, aber ich habe es durch das Schreiben der Kopfzeile auf die oben beschriebene Weise gelöst.

43voto

Seth Carnegie Punkte 72029

Sie haben

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

bevor die Cookies gesetzt werden, was nicht erlaubt ist. Sie können vor den Kopfzeilen keine Ausgabe senden, nicht einmal eine Leerzeile.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X