Stephan: Was ist falsch, nochmal ne Frage?

Hallo,

jetzt noch ein anderes Script:

Was ist hier falsch? Er sagt mir

Headers already send (error in link 169)

Line 169 ist

header("Location: lesen.php3?eintrag=". (int)mysql_insert_id()); // Benutzer auf den neuen Eintrag umleiten

Hier der gesamte Quellcode:

-----
<htm>
<head>

<?php
 include("funktionen.php3");     // Nützliche Funktionen importieren

unset($errors);  // Ein Array in das wir Fehlermeldungen schreiben
 unset($Thread);  // Variablen die evt. uninitialisiert benutzt werden, löschen

$connid = DBverbinden(); // Datenbankverbindung herstellen

if(!isset($eintrag) || $eintrag < 0) $eintrag = 0;
 else $eintrag = (int)$eintrag; // $eintrag auf einen vernünftigen Wert setzen

if($bearbeitet != true && $eintrag != 0) { // Es wurden keine Eingaben gemacht, und es soll eine Antwort verfasst werden
  $result = mysql_query("SELECT Betreff, Text FROM Forum WHERE ID =".$eintrag, $connid);
  if(!$result) die("Datenbank konnte nicht abgefragt werden");
  if(mysql_num_rows($result) != 1) { // Eintrag entweder nicht vorhanden oder mehrere Einträge mit derselben ID (hmm?)
   $errors[] = "Der Eintrag auf den Sie antworten wollen ist nicht in der Datenbank.
                Entweder existierte er nie und Sie spielen grade an den Formularparametern rum
                oder er wurde in der Zwischenzeit gelöscht.
                Wenn Sie dieses Formular abschicken, wird ein neuer Thread eröffnet.";
   $eintrag = 0; // Auf "neuen Thread" setzen
  } else {
   $eintragsdaten = mysql_fetch_array($result);
   $betreff = $eintragsdaten["Betreff"];  // Alte Betreffzeile übernehmen
   $text = $eintragsdaten["Text"]; // Alten Text übernehmen
   if(get_magic_quotes_runtime())
    $text = stripslashes($text); // Die Slashes die beim Auslesen freundlicherweise hinzugefügt werden entfernen
   $text = wordwrap($text); // Nachrichtentext automatisch umbrechen
   $text = preg_replace("/^/m", "> ", $text); // Zitatzeichen an den Anfang jeder Zeile stellen
   $text = addslashes($text); // Gleiche Ausgangsbedingungen für alle Variablen wiederherstellen
  }
 }

if($abschicken != "") { // Nachricht soll abgeschickt werden
  // Allgemeine Überprüfungen
  if(!isset($name) || $name == "")
   $errors[] = "Es wurde kein Name eingegeben. Bitte geben Sie einen Namen ein.";

if(!isset($betreff) || $betreff == "")
   $errors[] = "Es wurde keine Betreff-Zeile eingegeben. Bitte geben Sie eine Betreffzeile ein.";
  if($eintrag != 0) { // Es soll eine Antwort verfasst werden
   $result = mysql_query("SELECT TID FROM Forum WHERE ID=".$eintrag, $connid);
   if(!$result) die("Datenbank konnte nicht abgefragt werden");
   if(mysql_num_rows($result) != 1) { // Da ist irgendwas faul
    $errors[] = "Der Eintrag auf den Sie antworten wollen ist nicht in der Datenbank.
                 Entweder existierte er nie und Sie spielen grade am Formular rum
                 oder er wurde zwischenzeitlich gelöscht.
                 Wenn Sie das Formular erneut abschicken wird ein neuer Thread eröffnet.";
    $eintrag = 0;
   } else {
    list($Thread) = mysql_fetch_row($result);
   }
  }

if(!isset($errors)) { // Keine Fehler bisher, let's rock
   if($eintrag == 0) $Thread = 0; // neuer Thread
   $result = mysql_query("INSERT INTO Forum (PID, TID, AutorName, Betreff, AutorEmail, Text)
      VALUES (".$eintrag.",".$Thread.",'".$name."','".$betreff."',
             '".$email."','".$text."')", $connid);
   if(!$result) die("Konnte den neuen Eintrag nicht in die Datenbank schreiben");
   if($eintrag == 0) // Jetzt die Thread-ID des neuen Threads korrekt setzen
    if(!mysql_query("UPDATE Forum SET TID=ID, Zeitpunkt=Zeitpunkt WHERE ID = LAST_INSERT_ID()", $connid))
     die("Konnte die Thread-ID in der Datenbank nicht aktualisieren.
         Die Datenbasis könnte inkonsistent sein.");

// Wenn wir noch leben, dann ist alles glatt gegangen.
   header("Location: lesen.php3?eintrag=". (int)mysql_insert_id()); // Benutzer auf den neuen Eintrag umleiten
   exit(); // Skript beenden
  }
 }

// HTML-Teil
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
 <head>

<style type="text/css">

.style1 { styleangaben }

A.style1:active { font-weight: bold;  }

</style>

<?php if($eintrag == 0) { ?>
  <title>Neuen Eintrag verfassen</title>
<?php } else { ?>
  <title>Antwort verfassen</title>
<?php } ?>

</head>

<!-- Jetzt das Formular -->
 <body leftmargin="0" rightmargin="0" topmargin="0" bottom-margin="0" marginwidth="0" marginheight="0" class="weiss" >
<a name="anfang">

[Rest meiner Seite]

<td width="768" vAlign>
<?php if($eintrag == 0) { ?>
  <font face="arial"><span style="font-size:16px"><b>Neuen Eintrag verfassen</b>
<?php } else { ?>
  <span style="font-size:16px"><font face="arial"><b>Antwort verfassen</b>
  <p><font face="arial"><span style="font-size:15px">Im Formular ist der Eintrag auf den Sie antworten noch einmal komplett zitiert.
   Bitte löschen Sie beim Beantworten nicht benötigte Zitate.</p>
<?php } ?>
<?php if(isset($errors)) { /* es sind Fehler aufgetreten */?>
  <font face="arial"><span style="font-size:15px"><br><br><font color="#FF000000"><b>Fehler:</b></font>
  <p><font face="arial"><span style="font-size:15px">Beim Bearbeiten Ihrer Anfrage sind folgende Fehler aufgetreten:</p>
  <ul>
<?php foreach($errors as $error) { /* alle Fehler durchgehen */ ?>
   <li><?php wp($error);?></li>
<?php } ?>
<?php } ?>
  </ul>
  <font face="arial"><span style="font-size:15px"><b>Nachricht schreiben</b>
  <form action="neu.php3" method="POST">
   <!-- Der Eintrag auf den geantwortet wird, oder 0 für neuen Thread -->
   <input type="hidden" name="eintrag" value="<?php wp($eintrag);?>">

<!-- Damit die eingegeben Daten nicht aus der Datenbank überschrieben werden -->
   <input type="hidden" name="bearbeitet" value="true">

<font face="arial">Ihr Name:                 <input type="text" size="40" name="name" value="<?php wp($name);?>"><br>

<font face="arial">Ihre Mailaddresse:   <input type="text" size="40" name="email" value="<?php wp($email);?>"><br>

<font face="arial">Betreff:                     <input type="text" size="40" name="betreff" value="<?php wp($betreff);?>"><br>

<font face="arial">Nachrichtentext:<bR>

<textarea cols="40" rows="10" wrap="virtual" name="text"><?php wp($text);?></textarea><bR>

<?php if($eintrag == 0) { ?>
      <a href="index.php3?site=forum"><font face="arial">Abbrechen<br><small>Zur Hauptseite</small></a>
<?php } else { ?>
      <a href="lesen.php3?eintrag=<?php wp($eintrag);?>"><font face="arial">Abbrechen<br><small>Zum gelesenen Eintrag</small></a>
<?php } ?>

<input type="submit" name="abschicken" value="Abschicken"></td>
    </td></tr>
   </table>
  </form>
 </body>
</html>

-----------

Danke schon jetzt

Stephan

  1. Hi!

    Headers already send (error in link 169)

    Naja, eben was dransteht: der Datei-Header wurde schon an den Browser geschickt - und zwar automatisch, weil du schon vor dem Header was ausgegeben hast. Vor dem Header-befehl darf noch nix an den Browser gegangen sein...

    viele Grüße,
    benni

  2. Hallo!

    von dclp-faq.de:
    28.13. Warning: Cannot add header information - headers already sent ...
    http://www.dclp-faq.de/q/q-fehler-header.html

    Noch 2 Tipps:

    • verwende nach Möglichkeit einen aussagekräftigeren Titel
    • keine kompletten Scripte posten sondern wenns geht nur den relevanten Teil

    Grüße
    Andreas

  3. Hallo,

    Was ist hier falsch? Er sagt mir
    Headers already send (error in link 169)
      header("Location: lesen.php3?eintrag=". (int)mysql_insert_id()); // Benutzer auf den neuen Eintrag umleiten

    Warum es die Fehlermeldung gibt, steht in der dclp-FAQ:
    http://www.dclp-faq.de/q/q-fehler-header.html

    ---

    Die obige Zeile hat noch einen anderen Fehler:
    Die URL nach Location muss absolut/vollstaendig sein, also mit "http://" beginnen.

    http://www.php.net/manual/de/function.header.php#AEN30218
    "Anmerkung:  HTTP/1.1 verlangt einen absoluten URI inkl. dem Schema,
    Hostnamen und absoluten Pfad als Argument von Location:, aber manche
    Clients akzeptieren auch relative URIs."

    Der entsprechende Abschnitt in der HTTP/1.1 Spezifikation ist:
    http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30

    Es ist also Glueckssache, dass die Umleitung in einigen Browsern
    funktioniert; die URL muss unbedingt absolut sein.

    ---

    Es war unnoetig, die ganze Code-Wueste zu schicken.
    In Deinem Fall war der "Fehler" wirklich in der genannten Zeile.
    Ab und zu kommt es vor, dass er ein paar Zeilen weiter oben ist,
    z.B. bei nicht geschlossenen Anfuehrungszeichen oder geschweiften Klammern.

    Und bitte waehle das naechste mal ein aussagekraeftigeres Subject. </faq/#Q-06a>

    mfg
    Thomas

    1. Hallo,

      danke erstaml, aber wenn ich Header Location an den Anfang einfüge, kann man die Nachricht doch nicht mehr eingeben, oder?

      Danke schonmal

      Stephan

      1. Hallo,

        danke erstaml, aber wenn ich Header Location an den Anfang einfüge, kann man die Nachricht doch nicht mehr eingeben, oder?

        Du hast offenbar nicht begriffen, was Header() tut und wozu man es benutzt.

        Also, _entweder_ sendet das PHP-Skript einen HTTP-Header 302 mit Location:,
        dann wird der Browser auf eine andere Seite umgeleitet.
        (Dieser Seite kannst Du bei Bedarf Parameter weitergeben, indem Du sie
        an die URL dranhaengst.)
        Nach der Header-Ausgabe solltest Du das Skript beenden, z.B. mit die() oder exit().
        Wenn Du danach HTML-Code ausgibst, wird er von den meisten Browsern ignoriert.
        Steht uebrigens auch in der bereits genannten Seite:
        http://www.php.net/manual/de/function.header.php#AEN30218

        _Oder_ das PHP-Skript sendet eine HTML-Seite.
        Darin kann dann ein Formular stehen.
        Wenn Du _darin_ auf eine andere Seite weiterleiten willst,
        mach einen normalen Link hin.

        ----------

        Gruesse,

        Thomas

        P.S.
        Wenn Du _ganz_ vorbildlich sein willst, kannst Du nach dem HTTP-Header
        noch eine winzige HTML-Seite ausgeben, die einen normalen, klickbaren Link auf die
        Zielseite enthaelt. So verstehe ich zumindest die HTTP 1.1 Spezifikation:

        http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3
        "10.3.3 302 Found
        The temporary URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s)."