Warning: Cannot modify header information

Collapse
This topic is closed.
X
This is a sticky topic.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Warning: Cannot modify header information

    Warning: Cannot modify header information - headers already sent by (output started at /www/test.php:1) in /www/test.php on line 2

    Wie oft schon wurden (und werden noch immer) Fragen gestellt wie „Was bedeutet denn diese Fehlermeldung?“ oder „Wieso funktioniert mein Code nicht? Ich gebe doch vorher nichts aus.“
    Um nun ein für alle mal Licht in das Dunkel zu bringen, habe ich dieses kleine Manual verfasst.

    Grundsätzliches:
    Der header-Befehl sendet spezielle HTTP-Informationen und ist in etwa vergleichbar mit dem HTML-Tag <meta http-equiv…>

    So entspricht
    PHP Code:
    <meta http-equiv="refresh" content="0; URL=http://www.example.com"
    in etwa dem PHP-Befehl
    PHP Code:
    header ("Location: http://www.example.com"); 
    oder
    PHP Code:
    <meta http-equiv="pragma" content="no-cache"
    dem
    PHP Code:
    header ("Pragma: no-cache"); 
    Es gibt aber einen kleinen und sehr feinen Unterschied. In reinem HTML-Code werden die <meta…>-Anweisungen im Head-Bereich definiert, also zum Beispiel:
    PHP Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <
    html>
            <
    head>
                      <
    title>Blubb</title>
                      <
    meta http-equiv="refresh" content="0; URL=http://www.example.com">
                    </
    head>
                   <
    body>
                         

                   
    </body>
    </
    html
    Wenn man aber in PHP den header-Befehl benutzt, so darf vorher keine Ausgabe erzeugt werden. Das heißt einfach ausgedrückt, es darf nichts, aber auch wirklich gar nichts produziert werden, dass ein Browser darstellen kann. Dazu gehören HTML-Tags, stinknormale ASCII-Zeichen, Leerzeichen, Zeilenumbrüche oder PHP-Ausgaben z.B. mit echo oder print.

    Um zum Beispiel die oben aufgeführte Fehlermeldung zu bekommen, reicht schon ein einfaches Leerzeichen vor dem beginnenden PHP-Code aus.
    PHP Code:
    /*Hier müsst ihr euch jetzt ein Leerzeichen vorstellen*/<?
       header ("Location: http://www.example.com");
    ?>
    Ein Zeilenumbruch hat natürlich dieselbe Wirkung:
    PHP Code:
    /*Zeile 1:*/
    /*Zeile 2:*/ <?
    /*Zeile 3:*/     header (…);
    /*Zeile 4:*/ ?>
    So etwas wie:
    PHP Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <?
       header ("Location: http://www.example.com");
    ?>
    <title></title>
    </head>
        …
    ist da natürlich völliger Tinnef , da wir bereits in den ersten drei(!) Zeilen Daten ausgeben.

    Sehr beliebt ist auch der Fehler, Ausgaben in include-Dateien zu erzeugen und erst nachher den header-Befehl zu setzen. Ein kleines (zugegebenermaßen dummes) Beispiel soll das erklären. Wir haben eine Datei namens „test.php“:
    PHP Code:
    <?
    include ('css.php');
    if ($bla == 1) header ("Location: http://www.example.com");
    ?>
    In der css.php fragen wir nun den Browser ab, ist es der allseits beliebte Internet Explorer, so wird eine spezielle CSS-Datei eingebunden, anderenfalls eine Standard-Datei:
    PHP Code:
    <?
    if(ereg("MSIE", $_SERVER['HTTP_USER_AGENT']))
    {
       echo ‘<link rel="stylesheet" href="ie.css" type="text/css">’;
    }
    else
    {
       echo ‘<link rel="stylesheet" href="andere.css" type="text/css">’;
    }
    ?>
    Wenn jetzt $bla aus welchen Grund auch immer den Wert 1 hat, so wird folgende Fehlermeldung beim Aufruf der test.php(!) erzeugt:
    Warning: Cannot modify header information - headers already sent by (output started at /www/css.php:4) in /www/test.php on line x
    Anfänger machen dann sehr oft den Fehler, nicht in der eingebunden Datei (in diesem Fall css.php) sondern in der Hauptdatei (test.php) nach fehlerhaftem Code zu suchen, weil sie die Meldung nicht genau genug lesen. Die ist aber sehr detailliert:
    output started at /www/css.php:4
    Übersetzt heißt das, dass in der css.php in Zeile 4 eine Ausgabe erzeugt wurde. Also muss man auch dort suchen.

    Debugging:
    Ist in diesem Fall sehr einfach. Ihr bekommt im Browser eine Fehlermeldung à la „Cannot modify header….“, dann macht ihr einfach einen rechten Mausklick und wählt „Quelltext anzeigen“.

    Die eigentliche Fehlermeldung selber sieht dann so aus:
    PHP Code:
    <br />
    <
    b>Warning</b>:  Cannot modify header information … in <b></bon line <b></b><br /> 
    Und alles was vor dem ersten <br /> steht, ist eine Ausgabe, die IHR erzeugt habt. Da gibt es kein wenn und kein aber. Also lehnt euch zurück, raucht eine Zigarette (oder was anderes) und überlegt euch in aller Ruhe, wo das wohl herkommen mag. Dann ist es auch nicht schwierig, den Fehler zu finden.

    Ach übrigens, das selbe gilt auch bei der Verwendung von Sessions, zum Beispiel ein dummes Leerzeichen an der falschen Stelle und ihr habt das selbe Problem.
    Last edited by Kropff; 05-12-2005, 14:09.
    Nukular, das Wort ist N-u-k-u-l-a-r (Homer Simpson)
    Meine Seite

  • #2
    hmm, ich habs mir jetzt auch mal durchgelesen. Evtl. könnte man auch noch erklären was HTTP-Header sind und das sie nichts mit dem Head-Bereich im Html zu tun haben, auch wenn es hier diverse Metas gibt, die ähnliche Auswirkungen haben wie gewisse HTTP-Header.

    Wenn jemand eine (PHP)-Seite von einer Domain aufruft, schickt der Webserver vor dem eigentlichen Quelltext erst noch ein paar Infos ab - sowas kann so aussehen:

    Code:
    HTTP/1.0 200 OK
    Date: Mon, 05 Dec 2005 21:41:20 GMT
    Server: Apache/2.0.50 (Unix) mod_perl/1.99_14 Perl/v5.6.1 PHP/5.0.2
    X-Powered-By: PHP/5.0.2
    Cache-Control: max-age=0
    Expires: Mon, 05 Dec 2005 21:41:20 GMT
    Content-Length: 4973
    Connection: close
    Content-Type: text/html
    
    <html>
     <head>
      <title>Super Homepage</title>
      <meta .... />
      <meta .... />
     </head>
     <body>
       Wahnsinns-Content
     </body>
    </html>
    Alles was hier vor '<html>.....' steht sind die sogenannten HTTP-Header, also das, was ihr mit dem PHP-Befehl header(); beeinflussen könnt.

    Diese HTTP-Header sendet ein Webserver immer im voraus mit wenn er damit beginnt eine Seite an ihren Bestimmungsort zu schicken. Er sendet diese HTTP-Header ab, sobald auch nur ein einziges (Leer)zeichen an den Browser gesendet werden soll - ist dies geschehen, gibt es kein zurück mehr.

    Gebt ihr also auch nur ein einziges Zeichen aus (ich nehm ihm nachfolgenden Beispiel mal ein x anstelle eines Leerzeichens zur besseren sichtbarkeit) und verwendet dann später im Script z.B. einen header("Location: http://www.xyz.de/") -Befehl - würde eigentlich folgendes passieren:

    Code:
    HTTP/1.0 200 OK
    Date: Mon, 05 Dec 2005 21:41:20 GMT
    Server: Apache/2.0.50 (Unix) mod_perl/1.99_14 Perl/v5.6.1 PHP/5.0.2
    X-Powered-By: PHP/5.0.2
    Cache-Control: max-age=0
    Expires: Mon, 05 Dec 2005 21:41:20 GMT
    Content-Length: 4973
    Connection: close
    Content-Type: text/html
    
    xLocation: [url]http://www.xyz.de/[/url]
    Das wäre natürlich Blödsinn, denn der Browser würde das dann nicht mehr als HTTP-Header interpretieren, sondern als ganz normalen Quelltext (der beginnt immer nach dem ersten doppelten Zeilenumbruch nach der letzten Headerzeile) - PHP weiß nun aber dass die Header bereits abgesendet wurden und anstelle nun irgendwelchen Unsinn an den Browser zu senden, produziert PHP eine Fehlermeldung, die auf diesen Mißstand aufmerksam macht -> das vielzitierte:

    Code:
    Warning: Cannot modify header information - headers already sent 
    by (output started at /bli/bla/blub.php:80)
    Last edited by Quetschi; 05-12-2005, 23:08.
    Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
    Schön - etwas Geschichte kann ja nicht schaden.
    Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

    Comment

    Working...
    X