Fehler "Headers already sent"

Necro_nomicon

Erfahrenes Mitglied
Hallo!

Ich weiss, die Fehlermeldung steht auch unter haeufige Frage, leider kann ich damit mein Problem nicht umgehen, weil ich nicht genau weiss, wie ich es umgehen kann.
deswegen bitte nicht boese sein, dass ich hier trotzdem deswegen nachfrage.

Ich habe heute mein erstes komplett selbstgeschriebenes Formular geschrieben,
mit Hilfe angelesenem php-Wissen aus einem Buch.
Nun ist es so, dass bei allen Tests immer alles gut geklappt hat.
Nur in dem moment, wo man den code mit "location: form_confirm.php"
einfuegt kommt die Fehlermeldung: "Headers already sent"

Ich schlauen Buch ist nun beschrieben, dass man dieses "location" nicht vor
der Ausgabe eines HTML-Codes stellen darf, also hab ich es ganz oben in der
Datei reingegeben (siehe die ersten Zeilen von kontakt.php)
Das hat auch gefunkt.

Bis ich zu dem Punkt gekommen bin, dass ich mehrere Zeichen fuer die
Eingabefelder ueberpruefen lasse und diese Angaben in einer eigenen Datei
auslagere (form_validation.php) und diese dann mit der Zeile:

include ("form_validation.php");

direkt am Anfang des Php-Codes bei "if ($_POST['gesendet'] {...."
reingebe.


Nun passiert folgendes:
Wenn ich auf die kontakt.php gehe, dann werd ich automatisch
weitergeleitet auf die Datei form_confirm.php und kann also keine Nachricht hinterlassen.

Ich habe nun diverse Sachen bereits ausgeblendet, weil ich dachte, dass dort
vielleicht der Fehler liegt. Anscheinend liegt der Fehler aber darin, dass
ich nun seit dem include und dem geaenderten Code, die 3 Codezeilen mit
dem "location" nicht mehr oben einbinden darf.
Wenn ich diese naemlich rausgebe, dann hab ich ganz normal wieder die Seite
mit kontakt.php und dem Formular.

Die Frage ist nun wohl, wo ich den Teil mit "location: form_confirm.php"
einbinde im Code?
(Im Buch steht nur die hilfreiche Bemerkung: ...moment, ich zitiere:
Der "Headers already sent" ist ein sehr haeufiger und fuer Anfaenger sehr
frustrierender Fehler....

weiters steht: Dass man die include-Funktion des oberen Seitenbereichs bloss
in eine Zeile nach dem PHP, das die Seite umleitet, verschieben muss und dann
sei alles OK.
(ich habe einige Stellen probiert, bei mir war nichts OK)

Es soll ja erst das Kontaktformular dastehen, das man ausfuellen kann. Dann wird ueberprueft, ob eh kein Feld leer ist und ob die Felder bestimmte Zeichen beinhalten oder nicht beinhalten, danach soll dann das mail/die Nachricht abgeschickt werden und man wird weitergeleitet auf die Seite auf der steht: "Die Nachricht wurde erfolgreich verschickt".

An welcher Stelle muss ich den unten stehenden Code nun einfuegen? gebe ich ihn da rein, wo das Formular ist, dann kommt die Fehlermeldung mit dem header, geb ich es zu Seitenanfang, dann werde ich automatisch weitergeleitet.

PHP:
<?php

if (!$fehler_nachricht) { // wenn keine Fehler

	mail ($ziel_email, $email_betreff, $email_hauptteil); // Email verschicken

	header ('Location: form_confirm.php'); // auf neue Seite weiterleiten

	exit(); // Skript hier anhalten,

}

?>
 
Derzeit kommt der Fehler:
Umleitungsfehler:
Die aufgerufene Website leitet die Anfrage so um, dass sie nie beendet werden kann.

Gebe ich
PHP:
<?php

if (!$fehler_nachricht) { // wenn keine Fehler

	mail ($ziel_email, $email_betreff, $email_hauptteil); // Email verschicken

	header ('Location: form_confirm.php'); // auf neue Seite weiterleiten

	exit(); // Skript hier anhalten,

}

?>
raus vor dem Doctype, dann kommt der Fehler header already sent.


Was ich machen moechte:
Den Teil mit "location", der derzeit ganz oben vor dem Doctype steht an der richtigen Stelle einbinden, damit es mit der Weiterleitung klappt. Wenn es eine andere Art als location gibt, dann bin ich da auch nicht abgeneigt.

Hier das ganze kontakt.php
PHP:
<?php

if (!$fehler_nachricht) { // wenn keine Fehler

	mail ($ziel_email, $email_betreff, $email_hauptteil); // Email verschicken

	header ('Location: form_confirm.php'); // auf neue Seite weiterleiten

	exit(); // Skript hier anhalten,

}

?>

<?php

// nur fuer Test?

// if ($_POST['gesendet']){

//	echo "Formular gesendet!";

//	}

?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<meta name="keywords" content="">

<meta name="description" content="">

<link rel="stylesheet" type="text/css" href="style.css" media="screen">

<link rel="stylesheet" type="text/css" href="style_print.css" media="print">

<link rel="alternate stylesheet" type="text/css" title="smaller" href="smaller_style.css"> <!-- kleinere Schrift -->

<link rel="alternate stylesheet" type="text/css" title="bigger" href="bigger_style.css"> <!-- groessere Schrift -->

<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">





<title>Kontakt ::</title>



</head>

<body>



<div id="wrapper" class="clearfix">

     <div id="header"> 

	 		<img src="img/logo_weiss_sm.gif" width="400" height="56"></div>

     <div id="leftCol">

	 			

	 			<ul id="nav1">

					<li class="mainmenu"><a href="index.html"><span>Home</span></a></li>

					

					</ul>

	 			

				</div>

			

     <div id="rightCol">

	 </div>

	

    <div id="centerCol">

	 	

		

		<table cellpadding="0" cellspacing="5" border="0" width="735">

			

			<tr>

				<td valign="top">

				<h1>Kontaktformular</h1>

				<?php

				// include die Formularvalidierungsdatei

				include ("form_validation.php");

				

				

				if ($_POST['gesendet']){

					$vorname = $_POST['vorname'];

					$nachname = $_POST['nachname'];

					$email = $_POST['email'];

					$nachricht = $_POST['nachricht'];

					

				

				// Ausgabe nur fuer Test beim Schreiben des Formulars

				// echo $vorname; 

				// echo $nachname; 

				// echo $email; 

				// echo $nachricht; 

				

				// Schaltet Magic Quotes aus, wenn ein ist (Backslash) 

				if ( get_magic_quotes_gpc() ) {

					//Print "Magic Quotes sind an";

					$vorname = stripslashes($vorname);

					$nachname = stripslashes($nachname);

					$email = stripslashes($email);

					$nachricht = stripslashes($nachricht);

				}

				

				// Pruefung auf leere Felder 

				// $fehler_nachricht=0; 

				// if ($vorname=="") { 

				// 	$fehler_nachricht="Bitte geben Sie Ihren Vornamen ein"; 

				// } 

				

				// Fehlermeldung nur ausgeben, wenn Feld leer ist 

				// if ($fehler_nachricht) { 

				// 	echo ($fehler_nachricht); 

				// } 

				

				

				//  bei mehreren Fehlern: Fehlermeldungen in einem Array sammeln

				$fehler_nachricht=array();

					// wird ersetzt mit Prüfung auf falsches Zeichen

					// if ($vorname=="") {

					// $fehler_nachricht[] ="Bitte geben Sie Ihren Vornamen ein";

					// }

					$gueltig = verifiziereAlphaNum ($vorname);

					if (!$gueltig) {

						$fehler_nachricht[]="Der Vorname darf nur aus Buchstaben, Zahlen, Leerzeichen, Bindestrichen und # bestehen.";

					}

					

					// wird ersetzt mit Prüfung auf falsche Zeichen

					// if ($nachname=="") {

					// $fehler_nachricht[] ="Bitte geben Sie Ihren Nachnamen ein";

					// }

					$gueltig = verifiziereAlphaNum ($nachname);

					if (!$gueltig) {

						$fehler_nachricht[]="Der Nachname darf nur aus Buchstaben, Zahlen, Leerzeichen, Bindestrichen und ' bestehen.";

					}

					

					// wird ersetzt mit Pruefung auf falsches Zeichen

					// if ($email=="") {

					//$fehler_nachricht[] ="Bitte geben Sie Ihre E-Mail-Adresse ein";

					//}

					// wird ersetzt mit Prüfung auf mehrere falsche Zeichen

					// if (!strpo($email, "@")) {

					// 	$fehler_nachricht[] ="Bitte geben Sie eine gültige E-Mail-Adresse ein";

					// }

					$gueltig = verifiziereEmail ($email);

					if (!$gueltig) {

						$fehler_nachricht[]="Die E-Mail muss ein gültiges Format besitzen z.B. mustermann@gmx.at.";

					}

					

					// wird ersetzt mit Prüfung auf falsche Zeichen

					// if ($nachricht=="") {

					// $fehler_nachricht[] ="Sie haben keine Nachricht hinterlassen";

					// }

					$gueltig = verifiziereText ($nachricht);

					if (!$gueltig) {

						$fehler_nachricht[]="Die Nachricht darf nur Buchstaben, Zahlen und folgende Zeichen: \" ' - ? ! enthalten";

					}

					

				// gibt Fehlermeldung aus, nur zum testen 

				// foreach ($fehler_nachricht as $fehler) {

				//	echo ("$fehler <br>");

				//	}

					

				

				

				$ziel_email="necronomicon@gmx.at";

				$email_betreff="Mein Kontaktformular von der HP";

				$email_hauptteil="$vorname\n$nachname\n$nachricht\n$email";

				// nur zum Testen, dann weg

				//echo $email_hauptteil;

			  	// nun unten bei weiterleitung: mail ($ziel_email, $email_betreff, $email_hauptteil);

				// nur zum testen nun auf neue Seite leiten

				// print "E-mail versendet";



				



				}

				?>

				<div>

				

				

				<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">

				<!-- <form action="kontakt.php" method="POST"> -->

				

				

				<?php

				// Ausgabe Fehlernachrichten fuer leere Felder damit Ausgabe selbst platzieren kann

				if ($fehler_nachricht) {

					echo "<ul>\n";

						foreach ($fehler_nachricht as $fehler) {

						echo "<li>".$fehler."</li>\n";

						}

					echo "</ul>\n";

				}

				?>

				

				<label for="vorname">Vorname*</label>

				<input name="vorname" type="text" size="20" id="vorname" value="<?php echo $vorname ?>">

				<br>

				

				<label for="nachname">Nachname*</label>

				<input name="nachname" type="text" size="20" id="nachname" value="<?php echo $nachname ?>">

				<br>

				

				<label for="email">E-Mail*</label>

				<input name="email" type="text" size="20" id="email" value="<?php echo $email ?>">

				<br>

				

				<label for="nachricht">Nachricht</label>

				<textarea name="nachricht" rows="3" cols="20" id="nachricht"><?php echo $nachricht ?></textarea>

				<br>

				

				<input type="submit" name="gesendet" value="Senden">

				</form>

				</div>

				

				

				

			</td></tr></table>

			

							

		

  </div>

     <div id="footer">

	 
FOOTER

				</div>

	

	 	

  </div>

</div>







</body>

</html>
 
Zuletzt bearbeitet:
von der hier geposteten "kontakt.php", ganz oben mittels der location-Angabe vor dem Doctype:

die form_validation.php beinhaltet nur die Abfragen der verschiedenen Zeichen.
Der Vollstaendigkeitshalber hier die form_validation.php

PHP:
<?php

// print "included OK";

// prüfe auf Buchstaben, Zahlen, Bindestriche, Punkte, Leerzeichen, einfache Anfuehrungszeichen

function verifiziereAlphaNum ($testString) { 

	if (eregi ("^([[:alnum:]]|-|\.| |')+$", $testString)) {

		return 1;

		}

	else {

		return 0;

		}

	}

// prüfe valide Email Adresse

function verifiziereEmail ($testString) {

	if (eregi("^([[:alnum:]]|_|\.|-)+@([[:alnum:]]|\.|-)+(\.)([a-z]{2,4})$", $testString)) {

		return 1;

		}

	else {

		return 0;

		}

	}

// prüfe auf Buchstaben, Zahlen, Bindestriche, Leer-, Frage- und Ausrufezeichen, einfache und doppelte Anführungszeichen

function verifiziereText ($testString) {

	if (eregi("^([[:alnum:]]|-|\.| |\n|\r|\?|\!|\"|\'')+$", $testString)) {

		return 1;

		}

	else {

		return 0;

		}

	}

// prüfe auf valide Telefonnummer

function verifizierteTelefon ($testString) {

	if (eregi('^([[:digit:]]| |-)+$', $testString)) {

		return 1;

		}

	else {

		return 0;

		}

	}

	

?>
 
Zu der übergeordneten Datei; bspw. index.php, wovon das Formular gesendet wird die Funktion ob_start();(auch vor den Includes ;)) einfügen.

Wenn der Fehler mit der Umleitung auch nach einem Neustart von Apache und einem Browser restart immernoch kommen sollte dann liegt es wahrscheinlich am var $fehler_nachricht in deinem Code. Da ich deine php.ini nicht kenne, weiß ich ja leider nicht ob du Fehler anzeigen auf Aus hast. Wahrscheinlich stimmt da was mit dem Gültigkeitsbereich der Variable nicht..
 
Danke fuer deine Antwort. Leider ist mir schleierhaft, wie ich gemaess des Beispiels von deinem Link mit meiner Abfrage verfahren soll:(
Das ist leider in Programmiererdeutsch geschrieben fuer Leute, die schon programmieren koennen. Ich lerns ja erst.

Das mit der Variable kann ich aber erneut testen und die genaue Fehlermeldung posten. Allerdings stimmen die Zeilenangaben dann nicht, weil ich ja das HTML rausgenommen habe, damit es uebersichtlich bleibt.

Wie gesagt, bei allen Tests hat das Formular funktioniert, E-Mail verschickt usw.
Nur eben diese Weiterleitung will nicht. Mein "schlaues Buch" bietet dafuer leider auch keine Loesung, sondern verweist nur auf die Problematik an sich hin, was ziemlich enttaeuschend ist:(

Muss ich denn den Text "E-Mail erfolgreich versendet" ueberhaupt in einer neuen Seite darstellen? Kann ich das nicht in der gleichen Seite schreiben?

Und ich dachte ein Kontaktformular waere was einfaches zum anfangen *sigh*
 
PHP:
<?php
ob_start();

      
                // include die Formularvalidierungsdatei

                include ("form_validation.php");
                
                if (isset($_POST['gesendet'])&&$_POST['gesendet']=='Senden'){

                    $vorname = $_POST['vorname'];

                    $nachname = $_POST['nachname'];

                    $email = $_POST['email'];

                    $nachricht = $_POST['nachricht'];


                // Ausgabe nur fuer Test beim Schreiben des Formulars

                // echo $vorname; 

                // echo $nachname; 

                // echo $email; 

                // echo $nachricht; 

                // Schaltet Magic Quotes aus, wenn ein ist (Backslash) 

                if ( get_magic_quotes_gpc() ) {

                    //Print "Magic Quotes sind an";

                    $vorname = stripslashes($vorname);

                    $nachname = stripslashes($nachname);

                    $email = stripslashes($email);

                    $nachricht = stripslashes($nachricht);

                }

                

                // Pruefung auf leere Felder 

                // $fehler_nachricht=0; 

                // if ($vorname=="") { 

                //     $fehler_nachricht="Bitte geben Sie Ihren Vornamen ein"; 

                // } 

                

                // Fehlermeldung nur ausgeben, wenn Feld leer ist 

                // if ($fehler_nachricht) { 

                //     echo ($fehler_nachricht); 

                // } 

                

                

                //  bei mehreren Fehlern: Fehlermeldungen in einem Array sammeln

                $fehler_nachricht=NULL;

                    // wird ersetzt mit Prüfung auf falsches Zeichen

                    // if ($vorname=="") {

                    // $fehler_nachricht[] ="Bitte geben Sie Ihren Vornamen ein";

                    // }

                    $gueltig = verifiziereAlphaNum ($vorname);

                    if (!$gueltig) {

                        $fehler_nachricht[]="Der Vorname darf nur aus Buchstaben, Zahlen, Leerzeichen, Bindestrichen und # bestehen.";

                    }

                    

                    // wird ersetzt mit Prüfung auf falsche Zeichen

                    // if ($nachname=="") {

                    // $fehler_nachricht[] ="Bitte geben Sie Ihren Nachnamen ein";

                    // }

                    $gueltig = verifiziereAlphaNum ($nachname);

                    if (!$gueltig) {

                        $fehler_nachricht[]="Der Nachname darf nur aus Buchstaben, Zahlen, Leerzeichen, Bindestrichen und ' bestehen.";

                    }

                    

                    // wird ersetzt mit Pruefung auf falsches Zeichen

                    // if ($email=="") {

                    //$fehler_nachricht[] ="Bitte geben Sie Ihre E-Mail-Adresse ein";

                    //}

                    // wird ersetzt mit Prüfung auf mehrere falsche Zeichen

                    // if (!strpo($email, "@")) {

                    //     $fehler_nachricht[] ="Bitte geben Sie eine gültige E-Mail-Adresse ein";

                    // }

                    $gueltig = verifiziereEmail ($email);

                    if (!$gueltig) {

                        $fehler_nachricht[]="Die E-Mail muss ein gültiges Format besitzen z.B. mustermann@gmx.at.";

                    }

                    

                    // wird ersetzt mit Prüfung auf falsche Zeichen

                    // if ($nachricht=="") {

                    // $fehler_nachricht[] ="Sie haben keine Nachricht hinterlassen";

                    // }

                    $gueltig = verifiziereText ($nachricht);

                    if (!$gueltig) {

                        $fehler_nachricht[]="Die Nachricht darf nur Buchstaben, Zahlen und folgende Zeichen: \" ' - ? ! enthalten";

                    }


                // gibt Fehlermeldung aus, nur zum testen 

                // foreach ($fehler_nachricht as $fehler) {

                //    echo ("$fehler <br>");

                //    }


                $ziel_email="necronomicon@gmx.at";

                $email_betreff="Mein Kontaktformular von der HP";

                $email_hauptteil="$vorname\n$nachname\n$nachricht\n$email";

                // nur zum Testen, dann weg

                //echo $email_hauptteil;

                  // nun unten bei weiterleitung: mail ($ziel_email, $email_betreff, $email_hauptteil);

                // nur zum testen nun auf neue Seite leiten

                // print "E-mail versendet";



                



                }
              
if (is_array($fehler_nachricht)) { // wenn keine Fehler

    mail ($ziel_email, $email_betreff, $email_hauptteil); // Email verschicken

    header ('Location: form_confirm.php'); // auf neue Seite weiterleiten

    exit(); // Skript hier anhalten,

}

// nur fuer Test?

// if ($_POST['gesendet']){

//    echo "Formular gesendet!";

//    }

?>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<meta name="keywords" content="">

<meta name="description" content="">

<link rel="stylesheet" type="text/css" href="style.css" media="screen">

<link rel="stylesheet" type="text/css" href="style_print.css" media="print">

<link rel="alternate stylesheet" type="text/css" title="smaller" href="smaller_style.css"> <!-- kleinere Schrift -->

<link rel="alternate stylesheet" type="text/css" title="bigger" href="bigger_style.css"> <!-- groessere Schrift -->

<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">





<title>Kontakt ::</title>



</head>

<body>



<div id="wrapper" class="clearfix">

     <div id="header"> 

             <img src="img/logo_weiss_sm.gif" width="400" height="56"></div>

     <div id="leftCol">

                 

                 <ul id="nav1">

                    <li class="mainmenu"><a href="index.html"><span>Home</span></a></li>

                    

                    </ul>

                 

                </div>

            

     <div id="rightCol">

     </div>

    

    <div id="centerCol">

         

        

        <table cellpadding="0" cellspacing="5" border="0" width="735">

            

            <tr>

                <td valign="top">

                <h1>Kontaktformular</h1>

                <div>

                

                

                <form action="<?php echo $_SERVER['PHP_SELF']; /* unsicher... */ ?>" method="post">

                <!-- <form action="kontakt.php" method="POST"> -->

                

                

                <?php

                // Ausgabe Fehlernachrichten fuer leere Felder damit Ausgabe selbst platzieren kann

                if (is_array($fehler_nachricht)) {

                    echo "<ul>\n";

                        foreach ($fehler_nachricht as $fehler) {

                        echo "<li>".$fehler."</li>\n";

                        }

                    echo "</ul>\n";

                }

                ?>

                

                <label for="vorname">Vorname*</label>

                <input name="vorname" type="text" size="20" id="vorname" value="<?php echo $vorname ?>">

                <br>

                

                <label for="nachname">Nachname*</label>

                <input name="nachname" type="text" size="20" id="nachname" value="<?php echo $nachname ?>">

                <br>

                

                <label for="email">E-Mail*</label>

                <input name="email" type="text" size="20" id="email" value="<?php echo $email ?>">

                <br>

                

                <label for="nachricht">Nachricht</label>

                <textarea name="nachricht" rows="3" cols="20" id="nachricht"><?php echo $nachricht ?></textarea>

                <br>

                

                <input type="submit" name="gesendet" value="Senden">

                </form>

                </div>

                

                

                

            </td></tr></table>

            

                            

        

  </div>

     <div id="footer">

     
FOOTER

                </div>

    

         

  </div>

</div>

</body>

</html>
 
ah! Jetzt verstehe ich, das ganze kommt ueber die Ausgabe des HTMLs und nicht in das Formular rein!

und ob start(); steht zu Beginn ohne diese Zusaetze wie beim Beispiel mit Aepfel und Birnen bei dem link (http://at2.php.net/ob_start).

Danke, dass du dir die Zeit genommen und mein Formular angesehn hast, wodurch meine Freude am Lernen von PHP aufgrund meines Fehlers nicht erloschen ist.

Danke aber auch fuer deinen Hinweis, dass PHP_SELF unsicher ist.
In meinem Buch steht, dass man eben nicht die Domain nehmen sollte. Scheint also ein Fehler im Buch zu sein. Gibt es da eine sichere Variante oder ist das so ein Punkt wo viele diskutieren was am besten waere?
HTML:
<form action="<?php echo $_SERVER['PHP_SELF']; /* unsicher... */ ?>" method="post">

Ich werde das ganze einmal einbauen und am Server laden.

+++ edit +++
Spannend ist jetzt folgendes:
Wenn ich nicht alle Felder vom Formular ausfuelle, dann wird das Mail verschickt (kommt auch an) und ich werde auf naehcste Seite weitergeleitet mit der Nachricht, dass mein Mail erfolgreich versendet wurd.

Wenn ich jedoch alle Felder ausfuelle, dann wird keine Nachricht verschickt.

Aber am besten ist wohl, wenn ich mir den Code einfach nochmal morgen ausgeruht anschaue. Vielleicht habe ich da einen Logikfehler in meinen Abfragen.
 
Zuletzt bearbeitet:
Ich löse das Problem immer so, dass ich das Attribut action frei lasse. Das hat die gleiche Wirkung.

HTML:
<form method="post" action="">
  <div>
    <!-- ... --->
  </div>
</form>
 
Zurück