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




404 location (10)

Eine andere schlechte Praxis kann dieses Problem hervorrufen, das noch nicht angegeben ist.

Sehen Sie sich dieses Code-Snippet an:

<?php
include('a_important_file.php'); //really really really bad practise
header("Location:A location");
?>

Die Dinge sind in Ordnung, oder?

Was ist, wenn "a_important_file.php" das ist:

<?php
//some php code 
//another line of php code
//no line above is generating any output
?>

 ----------This is the end of the an_important_file-------------------

Das wird nicht funktionieren? Warum? Weil schon eine neue Zeile generiert wird.

Nun, obwohl dies kein gewöhnliches Szenario ist, was ist, wenn Sie ein MVC-Framework verwenden, das eine Menge Dateien lädt, bevor Sie die Dinge an Ihren Controller übergeben? Dies ist kein ungewöhnliches Szenario. Bereite dich darauf vor.

Von PSR-2 2.2:

  • Alle PHP-Dateien MÜSSEN das Unix LF (linefeed) line ending benutzen.
  • Alle PHP-Dateien MÜSSEN mit einer single blank line enden.
  • Das schließende?> - Tag MUSS in Dateien, die only php enthalten, omitted werden

Glauben Sie mir, nach diesen Standards können Sie eine Menge Stunden von Ihrem Leben retten :)

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

Warnung: Header-Informationen - Header, die bereits gesendet wurden, können nicht geändert werden ( Ausgabe gestartet unter /some/file.php:12 ) in /some/file.php in Zeile 23

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

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


Diese Fehlermeldung wird ausgelöst, wenn vor dem Senden von HTTP-Headern (mit setcookie() oder header() ) etwas gesendet wird. 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-Reihenfolge markiert 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 3F 3C . Sie können die BOM EF BB BF vom Anfang der Dateien sicher entfernen.
  • Explizite Ausgabe wie Aufrufe von echo , printf , readfile , passthru , Code vor <? etc.
  • Eine Warnung, die von PHP ausgegeben wird, wenn die php.ini-Eigenschaft display_errors gesetzt ist. Anstatt auf einen Programmierfehler zu stürzen, behebt php den Fehler und gibt eine Warnung aus. Während Sie die Konfigurationen display_errors oder error_reporting ändern können, sollten Sie das Problem eher beheben.
    Häufige Gründe sind Zugriffe auf undefinierte Elemente eines Arrays ( $_POST['input'] ohne isset() zu verwenden oder isset() zu testen, ob die Eingabe gesetzt ist) oder eine undefinierte Konstante anstelle eines String-Literals (wie in $_POST[input] , notiere die fehlenden Anführungszeichen).

Durch das Aktivieren der Pufferung von Ausgaben sollte das Problem verschwinden. Alle Ausgaben nach dem Aufruf von ob_start(); im Speicher zwischengespeichert, bis Sie den Puffer freigeben, z. B. 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.


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.


benutzen

ob_start ();

ganz oben in deinem Skript, und

ob_end_flush ();

am unteren Rand Ihres Skripts. Dadurch wird die Ausgabezwischenspeicherung aktiviert und Ihre Kopfzeilen werden erstellt, nachdem die Seite gepuffert wurde.

ALLGEMEINE PROBLEME:

======================

(kopierte Antwort von: source )

1) es sollte keine Ausgabe (dh echo.. oder HTML-Codes) vor dem header(.......); Befehl.

2) Entfernen Sie alle Leerstellen (oder Zeilenumbrüche ) vor den Tags <?php und after ?> .

3) GOLDENE REGEL! - Überprüfen Sie, ob diese PHP-Datei (und auch, wenn Sie andere Dateien enthalten) UTF8 ohne BOM- Codierung (und nicht nur UTF-8 ) haben. Das ist in vielen Fällen ein Problem (weil die UTF8- kodierte Datei am Anfang der PHP-Datei einen speziellen Charakter hat, den Ihr Texteditor nicht anzeigt) !!!!!!!!!!!

4) Nach header(...); Sie müssen den exit;

5) verwende immer 301 oder 302 Referenz:

header("location: http://example.com",  true,  301 );  exit;

6) Aktivieren Sie die Fehlerberichterstattung. Und erzähle den Fehler.

7) Wenn keine der oben genannten hilft, verwenden Sie die JAVSCRIPT-Umleitung (jedoch stark nicht empfohlene Methode), möglicherweise die letzte Chance in benutzerdefinierten Fällen ...:

echo "<script type='text/javascript'>window.top.location='http://website.com/';</script>"; exit;

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:

Sie haben möglicherweise Leerzeichen vor oder nach (am Ende der Datei nach?>), Dh

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 mit der Datei, die Sie require .

Hinweis: Manchmal EDITOR (IDE) wie gedit (ein Standard-Linux-Editor) fügen Sie eine leere Zeile bei speichern Datei speichern. 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 dies nicht der Fall ist, können Sie ob_start wie ob_start für die Pufferung von Ausgaben verwenden:

Mögliche Lösung 2:

<?php
  ob_start();

  // code 

 ob_end_flush();
?> 

Es ist wegen dieser Linie:

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

Bevor Sie die Header senden, sollten Sie nichts drucken / ausgeben.


Keine Ausgabe vor dem Senden der Header!

Funktionen, die HTTP-Header senden / ändern, müssen aufgerufen werden, bevor eine Ausgabe erfolgt . Zusammenfassung ⇊ Sonst schlägt der Anruf fehl:

Warnung: Header-Informationen können nicht geändert werden - bereits gesendete Header (Ausgabe gestartet am Skript: Zeile )

Einige Funktionen zum Ändern des HTTP-Headers sind:

Ausgabe kann sein:

  • Unbeabsichtigt:

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

    • print , echo und andere Funktionen zur Ausgabe
    • Raw <html> Abschnitte vor <?php code.

Warum passiert das?

Um zu verstehen, warum Header vor der Ausgabe gesendet werden müssen, ist es notwendig, eine typische HTTP Antwort zu betrachten. PHP-Skripte generieren hauptsächlich HTML-Inhalte, aber auch 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="/"> <img src=internal-icon-delayed> </a>

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

Wenn PHP die erste Ausgabe ( print , echo , <html> ) erhält , werden alle gesammelten Header gelöscht. Danach kann es alle gewünschten Ausgaben senden. Aber das Senden weiterer HTTP-Header ist dann unmöglich.

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

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

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

Hier bezieht sich "Zeile 100" auf das Skript, bei dem der Aufruf von header() fehlgeschlagen ist.

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

Typische Ursachen:

  1. Drucken, Echo

    Eine beabsichtigte Ausgabe von print und echo beendet die Möglichkeit, HTTP-Header zu senden. Der Anwendungsfluss muss neu strukturiert werden, um dies zu vermeiden. Verwenden Sie functions und Vorlagenschemata. Stellen Sie sicher, dass header() Aufrufe auftreten, bevor Nachrichten ausgegeben werden.

    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

    Nicht komprimierte HTML-Abschnitte in einer .php Datei werden ebenfalls direkt ausgegeben. Skriptbedingungen, die einen Aufruf von header() auslösen, müssen vor irgendwelchen rohen <html> -Blöcken notiert werden.

    <!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 vor <?php für "script.php line 1 " Warnungen

    Wenn sich die Warnung auf die Ausgabe in Zeile 1 bezieht, führt sie meistens Whitespace , Text oder HTML vor dem öffnenden <?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 verschlingt nach engeren Tags tatsächlich einen einzigen Zeilenumbruch. Es wird jedoch nicht mehrere Zeilenumbrüche oder Tabstopps oder Leerzeichen, die in solche Lücken verschoben wurden, ausgleichen.

  4. UTF-8 Stückliste

    Zeilenumbrüche und Leerzeichen können ein Problem sein. Es gibt aber auch "unsichtbare" Zeichenfolgen, die dies verursachen können. Am bekanntesten ist die UTF-8 BOM (Byte-Order-Mark), die von den meisten Texteditoren nicht angezeigt wird. Es ist die Bytefolge EF BB BF , die für UTF-8-codierte Dokumente optional und redundant ist. PHP muss es jedoch als Rohausgabe behandeln. Es kann sich als Zeichen  in der Ausgabe (wenn der Client das Dokument als Latin-1 interpretiert) oder ähnlichem» Müll «zeigen.

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

    Da ist es leicht, das Problem früh zu erkennen. Andere Editoren können ihre Anwesenheit in einem Datei- / Einstellungsmenü erkennen (Notepad ++ unter Windows kann das Problem identifizieren und beheben ). Eine weitere Möglichkeit, die Präsenz der Stücklisten zu überprüfen, besteht darin, einen Hexeditor zu verwenden . Auf * nix systems ist in der Regel hexdump verfügbar, wenn nicht eine grafische Variante, die diese und andere Probleme vereinfacht:

    Eine einfache Lösung besteht darin, den Texteditor so einzustellen, dass Dateien als "UTF-8 (keine BOM)" oder ähnliche Nomenklatur gespeichert werden. Neueinsteiger greifen oft auf neue Dateien zurück und kopieren und fügen den vorherigen Code wieder ein.

    Korrekturdienstprogramme

    Es gibt auch automatisierte Werkzeuge, um Textdateien ( sed/awk oder recode ) zu untersuchen und neu zu recode . Speziell für PHP gibt es den phptags tag ordner . Es schreibt die Tags close und open in lange und kurze Forms um, aber auch Probleme mit Leerzeichen und Leerzeichen, Unicode und UTF-x-BOM können problemlos behoben werden:

    phptags  --whitespace  *.php
    

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

  5. Whitespace nach ?>

    Wenn die Fehlerquelle als hinter dem Closing ?> Erwähnt wird, dann wurden einige Leerzeichen oder Rohtext ausgeschrieben. Der PHP-Endmarker beendet die Skriptausführung zu diesem Zeitpunkt nicht. Irgendwelche Text- / Leerzeichen-Zeichen werden danach als Seiteninhalt noch ausgeschrieben.

    Es wird allgemein empfohlen, insbesondere für Neueinsteiger, dass abschließende ?> PHP-Close-Tags weggelassen werden sollten. Dies meidet einen kleinen Teil dieser Fälle. (Ganz allgemein include()d Scripts dazu.)

  6. Fehlerquelle als "Unbekannt in Zeile 0"

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

    • Es ist gelegentlich die gzip Stream-Encoding-Einstellung oder der ob_gzhandler .
    • Es könnte aber auch jedes doppelt geladene extension= Modul sein, das eine implizite PHP Startup / Warnmeldung generiert.

  7. Vorangegangene Fehlermeldungen

    Wenn eine andere PHP-Anweisung oder ein Ausdruck dazu führt, dass eine Warnmeldung oder ein Hinweis ausgedruckt wird, gilt dies ebenfalls 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 das Debuggen später nicht behindert wird.

Keine Fehlermeldung

Wenn Sie per php.ini error_reporting oder display_errors deaktiviert php.ini , wird keine Warnung php.ini . Aber das Ignorieren von Fehlern wird das Problem nicht verschwinden lassen. Kopfzeilen können nach vorzeitiger Ausgabe noch nicht gesendet werden.

Wenn also header("Location: ...") stillschweigend umgeleitet wird, ist es sehr ratsam, nach Warnungen zu suchen. Erneut mit zwei einfachen Befehlen über dem Aufrufskript reaktivieren:

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 folgt für endgültige Code-Pfade verwenden:

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

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

Pufferung der Ausgabe als Workaround

Die Pufferung von PHP- Ausgaben ist eine Umgehungslösung, um dieses Problem zu beheben. Es funktioniert oft zuverlässig, sollte aber keine ordnungsgemäße Anwendungsstrukturierung ersetzen und die Ausgabe von der Steuerlogik trennen. Sein tatsächlicher Zweck ist die Minimierung von Chunked-Übertragungen an den Webserver.

  1. Die Einstellung output_buffering= kann trotzdem helfen. Konfigurieren Sie es in der php.ini oder über .htaccess oder sogar .user.ini in modernen FPM / FastCGI-Setups.
    Wenn Sie es aktivieren, kann PHP die Ausgabe puffern, anstatt sie sofort an den Webserver zu senden. PHP kann somit HTTP-Header aggregieren.

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

    • Auch wenn <?php ob_start(); ?> <?php ob_start(); ?> startet das erste Skript, Whitespace oder eine BOM wird möglicherweise vorher gemischt und unwirksam gemacht .

    • Es kann Leerzeichen für die HTML-Ausgabe verbergen. Aber sobald die Anwendungslogik versucht, binären Inhalt zu senden (beispielsweise ein erzeugtes Bild), wird die gepufferte Fremdausgabe ein Problem. ( 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 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 Ausgabepufferung nur als eine Krücke / strikt als Workaround betrachtet.

Siehe auch das grundlegende Anwendungsbeispiel im Handbuch und weitere Vor- und Nachteile:

Aber es hat auf dem anderen Server funktioniert !?

Wenn Sie die Header-Warnung zuvor nicht erhalten haben, hat sich die output_buffering= der output_buffering= geändert. Es ist wahrscheinlich auf dem aktuellen / neuen Server nicht konfiguriert.

Überprüfung mit headers_sent()

Sie können headers_sent() immer verwenden, um zu headers_sent() , ob es noch möglich ist ... Header zu senden. Dies ist nützlich, um eine Information bedingt auszudrucken oder eine 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 Fallback-Problemumgehungen sind:

  • HTML <meta> -Tag

    Wenn Ihre Anwendung strukturell schwer zu reparieren ist, dann ist es ein einfacher (aber etwas unprofessioneller) Weg, Weiterleitungen zuzulassen, ein HTML <meta> -Tag einzufügen. 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 Abschnitt <head> wird. Die meisten Browser akzeptieren es immer noch.

  • JavaScript-Weiterleitung

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

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

    Dies ist zwar oft HTML-kompatibler als die <meta> -Work-around-Methode, es wird jedoch auf JavaScript-fähige Clients zurückgegriffen.

Beide Ansätze machen jedoch akzeptable Fallbacks, wenn echte HTTP-Header () -Aufrufe fehlschlagen. Idealerweise würden Sie dies immer mit einer benutzerfreundlichen Nachricht und einem klickbaren Link als letzte Möglichkeit kombinieren. (Was zum Beispiel die http_redirect() PECL-Erweiterung tut.)

Warum sind setcookie() und session_start() ebenfalls betroffen session_start()

Sowohl setcookie() als auch session_start() müssen einen Set-Cookie: HTTP-Header senden. Daher gelten die gleichen Bedingungen und ähnliche Fehlermeldungen werden für vorzeitige Ausgabesituationen generiert.

(Natürlich sind sie auch im Browser von deaktivierten Cookies oder gar Proxy-Problemen betroffen. Die Session-Funktionalität hängt natürlich auch von freiem Speicherplatz und anderen php.ini-Einstellungen ab, etc.)

Weitere Links


Manchmal, wenn der Entwicklungsprozess sowohl WIN-Workstations als auch LINUX-Systeme (hosting) hat und im Code keine Ausgabe vor der zugehörigen Zeile angezeigt wird, könnte dies die Formatierung der Datei und das Fehlen von Unix LF (Zeilenvorschub) sein .

Was wir normalerweise tun, um dies schnell zu beheben, ist die Datei umzubenennen und auf dem LINUX-System eine neue Datei anstelle der umbenannten zu erstellen, und dann den Inhalt dorthin zu kopieren. Oftmals löst dies das Problem, da einige der Dateien, die in WIN erstellt wurden, einmal auf das Hosting verschoben wurden, was dieses Problem verursacht.

Dieser Fix ist eine einfache Lösung für Websites, die wir per FTP verwalten, und manchmal können unsere neuen Teammitglieder einige Zeit sparen.


Im Allgemeinen tritt dieser Fehler auf, wenn wir Header nach Echo oder Druck senden. Wenn dieser Fehler auf einer bestimmten Seite start_session() stellen Sie sicher, dass die Seite vor dem Aufruf von start_session() nichts start_session() .

Beispiel für einen unvorhersehbaren Fehler:

 <?php //a white-space before <?php also send for output and arise error
session_start();
session_regenerate_id();

//your page content

Ein weiteres Beispiel:

<?php
includes 'functions.php';
?> <!-- This new line will also arise error -->
<?php
session_start();
session_regenerate_id();

//your page content

Fazit: session_start() Sie kein Zeichen aus, bevor Sie die Funktionen session_start() oder header() aufrufen, nicht einmal ein Leerzeichen oder eine neue Zeile


cURL in PHP ist eine Brücke, um die Befehlszeile cURL aus der PHP-Sprache zu verwenden





php header