php-loser: Datenbankeintrag per Formular

Hallo allerseits!

Ich hatte schonmal ein Thema gestartet, das wurde aber leider gelöscht (wieso eigentlich?). Deswegen nochmal von vorn.

Ich versuch ein Formular zu basteln mit welchem Einträge in eine Datenbank geschrieben werden können. Bei falschen Angaben, soll das Formular erneut angezeigt werden mit entsprechenden Fehlermeldungen. Unter dem Formular sollen in jedem Fall (egal ob Formular bereits ausgefüllt oder nicht) die bereits eingegebenen Daten aus der Datenbank ausgelesen und angezeigt werden.

Rein funktional hatte ich das ganze eigentlich schon im letzten Thread geschafft, aber musste damals erfahren, dass mein Script weit davon entfernt war sauber programmiert zu sein. Deshalb mein neuer Versuch indem ich statt einer reiner Prozesssicht versucht habe das ganze in Module aufzuteilen und am Ende mit einem simplen Prozess auszuführen/anzuzeigen.

Ich habs mir etwa so vorgestellt:
Modul 1: Überprüfung ob bereits Daten abgesendet wurden
Modul 2: Das Formular an sich
Modul 3: Datenbankverbindung
Modul 4: Überprüfung der Eingaben
Modul 5: Datenbankeintrag
Modul 6: Datenbankabfrage und -ausgabe

Bisher hab ich das folgende Formular welches dann in die Index-Datei included werden soll:

<form action="<?php htmlspecialchars($_SERVER['PHP_SELF'])?>" method="post">  
	<fieldset>  
		<ul>  
			<li class="first">Event hinzufügen</li>  
			<?php if (isset($form_error[Input])){echo '<li class="error">'.$form_error[Input].'</li>';}?>  
			<?php if (isset($form_error[Datum])){echo '<li class="error">'.$form_error[Datum].'</li>';}?>  
			<li><label for="Datum">Datum:</label><input type="text" name="Datum" id="<?php if (isset($form_error[Datum])){echo 'fehler';} ?>" class="text" /></li>  
			<?php if (isset($form_error[Zeit])){echo '<li class="error">'.$form_error[Zeit].'</li>';}?>  
			<li><label for="Zeit">Zeit:</label><input type="text" name="Zeit" id="Zeit<?php if (isset($form_error[Zeit])){echo 'fehler';} ?>" class="text" /></li>  
			<?php if (isset($form_error[Ort])){echo '<li class="error">'.$form_error[Ort].'</li>';}?>  
			<li><label for="Ort">Ort:</label><input type="text" name="Ort" id="Ort<?php if (isset($form_error[Ort])){echo 'fehler';} ?>" class="text" /></li>  
			<?php if (isset($form_error[Adresse])){echo '<li class="error">'.$form_error[Adresse].'</li>';}?>  
			<li><label for="Adresse">Adresse:</label><input type="text" name="Adresse" id="Adresse<?php if (isset($form_error[Adresse])){echo 'fehler';} ?>" class="text" /></li>  
			<li class="last"><input type="submit" value="Hinzufügen" class="submit" /></li>  
		</ul>  
	</fieldset>  
</form>

Das Array form_error() ist so gedacht, dass in Modul 4 (Überprüfung der Eingaben) jeweils der entsprechende Wert mit einem String gefüttert werden soll. Z.B. bei der Eingabe von Buchstaben im Datumsfeld --> $form_error[Datum} = "Bitte gültiges Datum eingeben".

Soweit sogut. Nun hab ich aber bereits wieder ein Problem wenns darum geht die Eingaben zu überprüfen.
Wenn ich also nun folgendes prüfe:

  
if (isset ($_POST["Datum"], $_POST["Zeit"], $_POST["Ort"], $_POST["Adresse"])) {  
	if (empty ($_POST["Datum"])) {  
		$form_error[Input] = "Bitte alle Felder ausfüllen";  
	}  
}

..und es ist nichts eingegeben, dann wird zwar der Fehler angezeigt, aber der Rest wird trotzdem fortgesetzt inklusive Datenbankeintrag. Und wenn ich mit "die" Arbeiten würde, würde der Rest garnicht nicht mehr ausgeführt werden (also auch die restliche anzeige der Fehler, was ich auch nicht wirklich möchte.

Ich steh grad irgendwie voll planlos da. Kann mir jemand einen Schubs in die richtige Richtung geben?

Besten Dank im Voraus.
php-loser

PS: bitte nicht diesen Thread auch wieder löschen.. ist ziemlich anstrengend alles wieder von vorne zu erzählen.

  1. Hallo,

    Ich hatte schonmal ein Thema gestartet, das wurde aber leider gelöscht (wieso eigentlich?). Deswegen nochmal von vorn.

    nein, dein früherer Betrag ist nicht gelöscht worden, sondern einfach nur archiviert (das passiert automatisch, wenn eine gewisse Zeit lang keine Beiträge mehr hinzukommen). Deswegen kannst du dich auch gern auf die vorhandenen Beiträge beziehen.

    So long,
     Martin

    --
    Wenn zwei dasselbe tun, sind sie vielleicht bald zu dritt.
  2. echo $begrüßung;

    Ich habs mir etwa so vorgestellt:
    Modul 1: Überprüfung ob bereits Daten abgesendet wurden
    Modul 2: Das Formular an sich
    Modul 3: Datenbankverbindung
    Modul 4: Überprüfung der Eingaben
    Modul 5: Datenbankeintrag
    Modul 6: Datenbankabfrage und -ausgabe

    Das Formular muss doch wissen, ob es Fehler gab, damit diese angezeigt werden können und/oder die betreffenden Felder markiert werden können. Weiterhin braucht es zur Eingabedatenprüfung keine Datenbankverbindung.

    Schritt 1: Überprüfung der Eingaben
    Schritt 2: Datenverarbeitung
    Schritt 2a: Datenbankeintrag nur wenn es keine Fehler gab
    Schritt 2b: Datenabfrage
    Schritt 3: Ausgabe. Das grundlegende Seitengerüst wird ergänzt um:
    Schritt 3a: Das Formular plus eventueller Anzeige von Fehlern
    Schritt 3b: Ausgabe der Datenbankabfrage

    Wenn ich also nun folgendes prüfe:
    ..und es ist nichts eingegeben, dann wird zwar der Fehler angezeigt, aber der Rest wird trotzdem fortgesetzt inklusive Datenbankeintrag. Und wenn ich mit "die" Arbeiten würde, würde der Rest garnicht nicht mehr ausgeführt werden (also auch die restliche anzeige der Fehler, was ich auch nicht wirklich möchte.

    Du hast ja im Prüfschritt festgestellt, ob Fehler vorhanden sind oder nicht. Die nachfolgenden Teile können orüfen, ob es Fehler gab oder nicht und dann entsprechend arbeiten oder nicht.

    echo "$verabschiedung $name";

    1. Schritt 1: Überprüfung der Eingaben
      Schritt 2: Datenverarbeitung
      Schritt 2a: Datenbankeintrag nur wenn es keine Fehler gab
      Schritt 2b: Datenabfrage
      Schritt 3: Ausgabe. Das grundlegende Seitengerüst wird ergänzt um:
      Schritt 3a: Das Formular plus eventueller Anzeige von Fehlern
      Schritt 3b: Ausgabe der Datenbankabfrage

      »»

      Aber ich dachte doch genau diese Denkweise sei zu vermeiden?! Klar... am Ende muss das ganze so zusammengefügt werden und zwar in der Reihenfolge wie Du es genannt hast. Aber die einzelnen Schritte sollten - so dachte ich aufgrund der mir gegebenen Antworten - sollten in an und für sich selbständige Module aufgeteilt werden welche am Ende durch die Ergebnisvariablen aus den Modulen in diese Schritte zusammengeführt werden?!

      Scheint aber x-tausend verschiedene Ansichten zu geben wie sowas zu scripten sei ... kein Wunder bin ich mit jeder Antwort nur mehr verwirrter als vorher...

      1. Hallo,

        »» Schritt 1: Überprüfung der Eingaben
        »» Schritt 2: Datenverarbeitung
        »» Schritt 2a: Datenbankeintrag nur wenn es keine Fehler gab
        »» Schritt 2b: Datenabfrage
        »» Schritt 3: Ausgabe. Das grundlegende Seitengerüst wird ergänzt um:
        »» Schritt 3a: Das Formular plus eventueller Anzeige von Fehlern
        »» Schritt 3b: Ausgabe der Datenbankabfrage

        Aber ich dachte doch genau diese Denkweise sei zu vermeiden?!

        wie kommst du darauf?

        Aber die einzelnen Schritte sollten - so dachte ich aufgrund der mir gegebenen Antworten - sollten in an und für sich selbständige Module aufgeteilt werden welche am Ende durch die Ergebnisvariablen aus den Modulen in diese Schritte zusammengeführt werden?!

        Ja, schon. Aber diese "selbständigen Module" sollten natürlich nicht getrennte Ressourcen oder Scripte sein, sondern nur getrennte Denkschritte, die im fertigen Script noch klar teilbar sind. Aber sie gehören natürlich in einem Script zusammen.

        Und anhand der von dedlfix skizzierten Struktur kann man auch das E-V-A-Prinzip immer noch klar erkennen: 1=Eingabe, 2=Verarbeitung, 3=Ausgabe.

        So long,
         Martin

        --
        Du kannst dem Leben nicht mehr Tage geben.
        Aber dem Tag mehr Leben.
    2. Soooo!

      Ich hab nochmal wie blöd gebastelt und dabei kam folgendes raus:

      Die add_event.php:

      <?php session_start ();  
        
      require ('settings.php');  
        
      $connectionid = mysql_connect($db_host, $db_user, $db_pass);  
      $db_selected = mysql_select_db($db_name, $connectionid);  
        
      if (isset ($_POST['Datum'], $_POST['Zeit'], $_POST['Ort'], $_POST['Adresse'])) {  
      	if (empty ($_POST['Datum']) || empty($_POST['Zeit']) || empty($_POST['Ort']) || empty($_POST['Adresse'])) {  
      		$form_error['Input'] = "Bitte alle Felder ausfüllen";  
      		die(); // da sonst das script weiter durchlaufen wird (auch der DB-Eintrag)  
      	}  
      	  
      	// alle Slashes in superglobalen arrays löschen  
      	if (get_magic_quotes_gpc()) {  
      		$in = array(&$_GET, &$_POST, &$_COOKIE);  
      		while (list($k,$v) = each($in)) {  
      			foreach ($v as $key => $val) {  
      				if (!is_array($val)) {  
      					$in[$k][$key] = stripslashes($val);  
      					continue;  
      				}  
      				$in[] =& $in[$k][$key];  
      			}  
      		}  
      		unset($in);  
      	}  
      	  
      	// Überprüfung Datumfeld  
      	// $form_error['Datum'] = "Kein gültiges Datum angegeben."  
        
      	// Überprüfung Zeitfeld  
      	// $form_error['Zeit'] = "Keine gültige Zeitangabe."  
        
      	// Überprüfung Adressfeld  
      	  
      	  
      	  
        
        
        
      	if (count($form_error) == 0) {  
      			if (!$connectionid) {  
      				die('Verbindung nicht möglich : ' . mysql_error());  
      			}  
        
      			if (!$db_selected) {  
         			 	die ('Kann Datebank nicht benutzen : ' . mysql_error());  
      			}  
      			else {  
      			$sql = "INSERT INTO agenda (Datum, Zeit, Ort, Adresse) VALUES ('".$_POST['Datum']."', '".$_POST['Zeit']."', '".$_POST['Ort']."', '".$_POST['Adresse']."')";  
      		  
      			if (!mysql_query($sql,$connectionid)) {  
      				die('Eintrag nicht möglich : ' . mysql_error());  
      			}  
      		}	  
      	}  
      }  
        
      // Ausgabe des Formulars  
      include ('htmlform.php');  
        
        
      // Ausgabe der bestehenden Einträge (bisher unformatiert)  
      $q = mysql_query("SELECT Datum, Zeit, Ort, Adresse FROM agenda");  
        
      while($r = mysql_fetch_assoc($q)) {  
      	$arr[] = $r;  
      }  
        
      echo "<pre>";  
      print_r($arr);  
      echo "</pre>";  
        
      ?> 
      

      und die Datei htmlform.php in welcher das Formular ist (getrennt, da es so einfacher "gewartet" werden kann.

      <form action="<?php htmlspecialchars($_SERVER['PHP_SELF'])?>" method="post">  
      	<fieldset>  
      		<ul>  
      			<li class="first">Event hinzufügen</li>  
      			<?php if (isset($form_error['Input'])){echo '<li class="error">'.$form_error['Input'].'</li>';}?>  
      			<?php if (isset($form_error['Datum'])){echo '<li class="error">'.$form_error['Datum'].'</li>';}?>  
      			<li><label for="Datum">Datum:</label><input type="text" name="Datum" id="<?php if (isset($form_error[Datum])){echo 'fehler';} ?>" class="text" /></li>  
      			<?php if (isset($form_error[Zeit])){echo '<li class="error">'.$form_error[Zeit].'</li>';}?>  
      			<li><label for="Zeit">Zeit:</label><input type="text" name="Zeit" id="Zeit<?php if (isset($form_error[Zeit])){echo 'fehler';} ?>" class="text" /></li>  
      			<?php if (isset($form_error[Ort])){echo '<li class="error">'.$form_error[Ort].'</li>';}?>  
      			<li><label for="Ort">Ort:</label><input type="text" name="Ort" id="Ort<?php if (isset($form_error[Ort])){echo 'fehler';} ?>" class="text" /></li>  
      			<?php if (isset($form_error[Adresse])){echo '<li class="error">'.$form_error[Adresse].'</li>';}?>  
      			<li><label for="Adresse">Adresse:</label><input type="text" name="Adresse" id="Adresse<?php if (isset($form_error[Adresse])){echo 'fehler';} ?>" class="text" /></li>  
      			<li class="last"><input type="submit" value="Hinzufügen" class="submit" /></li>  
      		</ul>  
      	</fieldset>  
      </form>
      

      Nun hab ich aber noch mehrere Probleme, bei denen ich nicht weiterkomme. Gerne würde ich das Schritt für Schritt durchgehen, weil ihr sonst wohl gleich wieder mit umfassenden Antworten auf mich einschlagt von welchen ich nur knapp 1% verstehe. Und bitte antwortet so einfach wie möglich, sonst komm ich bei euren Antworten nicht nach.

      Problem 1: Beim ersten laden erscheint das Formular korrekt. Wenn man (korrekte) Eingaben tätigt, werden sie erfolgreich in die Datenbank geschrieben und das Formular sowie die eingetragenen erneut angezeigt. Wenn man alles leer lässt oder nur ein Feld ausfüllt und auf "Hinzufügen" klickt, erscheint nur eine leere Seite. Eigentlich sollte das Formular mit den entsprechenden Fehlermeldungen angezeigt werden.

      Problem 2: Die Daten können zwar nur von einer Person eingegeben werden und die weiss wie sie sie eingeben muss, aber dennoch möchte ich die Eingaben überprüfen und in ein für die Datenbank sinnvolles Format bringen (sofern es nicht bereits so ist.) Wie kann ich also überprüfen ob eine gültige Zeit xx:xx und ein gültiges Datum xx.xx.xxxx oder xxxx-xx-xx  (--> für die Datenbank umwandeln in xx.xx.xxxx) eingegeben wurde?

      1. Ach wie doof.

        Den Fehler für das erste Problem habe ich gefunden.

        Es lag am:
        die(); // da sonst das script weiter durchlaufen wird (auch der DB-Eintrag)

        Bleibt noch das Problem 2:

        Problem 2: Die Daten können zwar nur von einer Person eingegeben werden und die weiss wie sie sie eingeben muss, aber dennoch möchte ich die Eingaben überprüfen und in ein für die Datenbank sinnvolles Format bringen (sofern es nicht bereits so ist.) Wie kann ich also überprüfen ob eine gültige Zeit xx:xx und ein gültiges Datum xx.xx.xxxx oder xxxx-xx-xx  (--> für die Datenbank umwandeln in xx.xx.xxxx) eingegeben wurde?

        Könnt ihr mir da weiterhelfen? Oder ist sonstnoch etwas total falsch gemacht?

        Liebe Grüsse
        php-loser

      2. echo $begrüßung;

        $connectionid = mysql_connect($db_host, $db_user, $db_pass);
        $db_selected = mysql_select_db($db_name, $connectionid);

        Du bist hier noch am Scriptanfang und weißt gar nicht, ob du überhaupt eine Datenbankverbindung brauchst. Im Falle eines Fehlers nämlich drehst du ja noch eine Formularausfüllrunde ohne das DBMS zu behelligen. Trotzdem öffnest du die Verbindung. Und ohne zu prüfen, ob das geklappt hat, versuchst du gleich darauf die zu verwendende Datenbank zu selektieren. Bau doch mal einen Tippfehler in die Zugangsdaten ein oder fahr den MySQL-Server runter. Dann siehst du, dass das Selektieren der Datenbank einen Folgefehler bringt. Erst viel weiter unten prüfst du, ob die Verbindung erfolgreich war.

        Verbesserungsvorschläge: Prüfe direkt nach dem Verbindungsaufbau, ob er von Erfolg gekrönt war oder nicht. Prüfe beim Entwickeln immer auch den Schlechtfall, beispielsweise mit falschen Zugangsdaten. Gestalte die Vorgänge in deinem Ablauf so, dass sie nicht auseinandergenommen werden. Die DB-Verbindung brauchst du erst nach der erfolgreichen Prüfung der Eingabedaten, also erzeuge sie auch erst dann.

        if (isset ($_POST['Datum'], $_POST['Zeit'], $_POST['Ort'], $_POST['Adresse'])) {
        if (empty ($_POST['Datum']) || empty($_POST['Zeit']) || empty($_POST['Ort']) || empty($_POST['Adresse'])) {

        isset() und empty() ist doppelt gemoppelt. Wenn du empty() verwendest, kannst du die isset()-Prüfung weglassen.

          $form\_error['Input'] = "Bitte alle Felder ausfüllen";  
          die(); // da sonst das script weiter durchlaufen wird (auch der DB-Eintrag)  
        

        Haste ja selbst schon gemerkt.

        // alle Slashes in superglobalen arrays löschen

        Diesen Vorgang solltest du ganz am Scriptanfang einfügen. Eingabedaten in eine brauchbares Format (Rohform) zu bringen, sollte der erste Schritt sein (EVA-Prinzip). Und außerdem solltest du das gemäß dem Beispiel im PHP-Handbuch einfügen. Das berücksichtigt nämlich auch verschachtelte Strukturen.

          while (list($k,$v) = each($in)) {  
          	foreach ($v as $key => $val) {  
        

        Seit es foreach gibt, braucht man das Gespann while-list-each nicht mehr.

        if (count($form_error) == 0) {

        Aufgrund PHPs automatischer Typkonvertierung brauchst du das Ergebnis von count() nicht noch mit einer Zahl zu vergleichen. Du kannst es gleich als boolschen Wert ansehen, allerdings mit umgekehrter Logik in dem Fall.

        if (! count($form_error)) {

        Und noch viel besser: Du kannst auch direkt auf das Array prüfen, denn ein leeres Array ergibt auch false.

        if (! $form_error) {

        Außerdem hast du vergessen, $form_error definitiv anzulegen. Wenn kein Fehler auftritt, schreibst du nichts rein, wodurch es nicht implizit angelegt wird. Ein Lesezugriff auf etwas nicht vorhandenes ist normalerweise ein Fehler. PHP informiert darüber aber nur, wenn man es explizit darum bittet: mit auf E_ALL gestelltem error_reporting. Das ist beim Entwickeln immer empfehlenswert, bekommt man doch damit auch fehlerhafte Zugriffe aufgrund von Schreibfehlern angezeigt. Bevor du also die Prüfungen beginnst:

        $form_error = array();

          	if (!$connectionid) {  
          		die('Verbindung nicht möglich : ' . mysql\_error());  
        

        Wie gesagt, schreib die mysql_connect-Zeile direkt vor diese beiden Zeilen und ...

          	if (!$db\_selected) {  
        

        die ('Kann Datebank nicht benutzen : ' . mysql_error());

        die mysql_select_db-Zeile hier davor.

        Außerdem ist es besser, statt das Script sterben zu lassen und dabei noch alle Welt mit technischen Details zu behelligen, wenn du im Fehlerfall einen alternativen Weg gehst (if-else) und damit zum einen das Script ordentlich beendest und zum anderen die Fehlermeldung nur an den Administrator leitest.

          	else {  
          	$sql = "INSERT INTO agenda (Datum, Zeit, Ort, Adresse) VALUES ('".$\_POST['Datum']."', '".$\_POST['Zeit']."', '".$\_POST['Ort']."', '".$\_POST['Adresse']."')";  
        

        Hier fehlt die kontextgerechte Behandlung der Werte. Wenn jemand als Ort D'dorf eingibt, bekommst du nur einen Syntaxfehler. Wenn jemand diese SQL-Injection-Lücke gezielter ausnutzt, ...
        mysql_real_escape_string() heißt das Stichwort.

        // Ausgabe des Formulars
        include ('htmlform.php');

        Nebenbei: include ist keine Funktion. Die Klammern kannst du weglassen. (Die Anführungszeichen müssen aber bleiben.)

        while($r = mysql_fetch_assoc($q)) {
        $arr[] = $r;

        Auch hier wieder: Vor der Schleife sollte $arr explizit als leeres Array angelegt werden. Wenn es nämlich nichts zu Fetchen gibt, wird $arr nicht angelegt und ...

        print_r($arr);

        ... auch wenn das hier nur eine Kontrollausgabe ist, greift in dem Fall auf etwas nicht vorhandenes zu.

        [code lang=php]<form action="<?php htmlspecialchars($_SERVER['PHP_SELF'])?>" method="post">

        Hier fehlt ein echo.

          	<li><label for="Datum">Datum:</label><input type="text" name="Datum" id="<?php if (isset($form\_error[Datum])){echo 'fehler';} ?>" class="text" /></li>  
          	<li><label for="Zeit">Zeit:</label><input type="text" name="Zeit" id="Zeit<?php if (isset($form\_error[Zeit])){echo 'fehler';} ?>" class="text" /></li>  
        

        Eine id muss ein eindeutiger Wert sein. Im Falle mehrerer Fehler vergibst du die ID "fehler" mehrmals. Außerdem brauchst du die id eigentlich um mit <label for="..."> zusammenzuarbeiten. Besser ist es class zu verwenden. Dass du es hier schon mit "text" belegt hast, macht nichts, class kann man mehrere Werte durch Leerzeichen getrennt zuweisen.

        Und dann möchtest du vielleicht das value-Attribut der input-Elemente mit dem Wert aus der Eingabe vorbelegen, so dass im Falle eines Fehlers in einem Feld der Anwender nicht alles noch einmal einzugeben hat.

        Nun hab ich aber noch mehrere Probleme, bei denen ich nicht weiterkomme. Gerne würde ich das Schritt für Schritt durchgehen, weil ihr sonst wohl gleich wieder mit umfassenden Antworten auf mich einschlagt von welchen ich nur knapp 1% verstehe.

        Tja, um meine Antwort kürzer ausfallen zu lassen, fand ich zu wenig Gründe.

        Und bitte antwortet so einfach wie möglich, sonst komm ich bei euren Antworten nicht nach.

        Wenn du etwas nicht verstehst, frag bitte konkret nach. Erläuter auch bitte kurz, inwieweit du es schon verstanden hast beziehungsweise was genau das Verständnisproblem ist.

        Problem 2: Die Daten können zwar nur von einer Person eingegeben werden und die weiss wie sie sie eingeben muss, aber dennoch möchte ich die Eingaben überprüfen und in ein für die Datenbank sinnvolles Format bringen (sofern es nicht bereits so ist.) Wie kann ich also überprüfen ob eine gültige Zeit xx:xx und ein gültiges Datum xx.xx.xxxx oder xxxx-xx-xx  (--> für die Datenbank umwandeln in xx.xx.xxxx) eingegeben wurde?

        MySQL hätte das Datum gern im Format JJJJ-MM-TT (oder als date()-Format-String: Y-m-d).

        Es gibt (wie immer) mehrere Wege, so auch für eine solche Prüfung. Zum einen könntest du das Format auf syntaktische Korrektheit prüfen. Bei einer Uhrzeit wäre das

        optionale Ziffer - Ziffer - Doppelpunkt (oder anderes Trennzeichen) - Ziffer - Ziffer

        Für die Syntax-Prüfung kann man einen Regulären Ausdruck verwenden. Dann gibt es aber immer noch die Möglichkeit, ungültige Werte einzugeben wie 25:90. Eine Uhrzeit zu prüfen ist ja noch relativ einfach. Man trennt die Angabe in Einzelwerte und vergleicht auf das Einhalten der Grenzen (für Stunden, Minuten und Sekunden). Prinzipiell kann man das bei einem Datum genauso machen, allerdings ist die Prüfung hier komplexer. Aber PHP macht es einfach, es gibt die Funktion checkdate().

        Die zum Prüfen erzeugten Einzelwerte fügst du bei Fehlerfreiheit mit dem korrekten Trennzeichen so zusammen, wie MySQL sie haben will und fertig ist.

        Eine Alternative ist, mit strptime() die Einabe zu analysieren. Hier solltest du aber mit ein paar Tests auch unsinniger Eingaben Erfahrungen sammeln, wie sich strptime() verhält und ob dir das so gefällt.

        Außerdem gibt es noch strtotime(), das in allen möglichen Werten was Brauchbares zu finden versucht und das vorzugsweise bei englischer Notation. Für deutsche Benutzereingaben würde ich diese Funktion nicht verwenden, dann schon eher strptime().

        echo "$verabschiedung $name";

        1. Hi und Danke erstmal!

          Du bist hier noch am Scriptanfang und weißt gar nicht, ob du überhaupt eine Datenbankverbindung brauchst. Im Falle eines Fehlers nämlich drehst du ja noch eine Formularausfüllrunde ohne das DBMS zu behelligen. Trotzdem öffnest du die Verbindung. Und ohne zu prüfen, ob das geklappt hat, versuchst du gleich darauf die zu verwendende Datenbank zu selektieren. Bau doch mal einen Tippfehler in die Zugangsdaten ein oder fahr den MySQL-Server runter. Dann siehst du, dass das Selektieren der Datenbank einen Folgefehler bringt. Erst viel weiter unten prüfst du, ob die Verbindung erfolgreich war.

          Ok, verstanden, aber dann muss ich die Verbindung nochmals neu öffnen wenn ich zur Datenbankabfrage (und dem Auslesen der Tabelle), da die Verbindung nur aufgebaut wird, wenn die Eingaben geprüft und behandelt wurden (und fehlerfrei sind), richtig? Das Auslesen soll ja aber in jedem Fall geschen.

          »» // alle Slashes in superglobalen arrays löschen

          Diesen Vorgang solltest du ganz am Scriptanfang einfügen. Eingabedaten in eine brauchbares Format (Rohform) zu bringen, sollte der erste Schritt sein (EVA-Prinzip)

          Ok.. danke für den Link :).

          Und noch viel besser: Du kannst auch direkt auf das Array prüfen, denn ein leeres Array ergibt auch false.

          if (! $form_error) {

          cool :). Eigentlich super logisch, aber ich wär nie von selbst drauf gekommen.

          Außerdem hast du vergessen, $form_error definitiv anzulegen. Wenn kein Fehler auftritt, schreibst du nichts rein, wodurch es nicht implizit angelegt wird. Ein Lesezugriff auf etwas nicht vorhandenes ist normalerweise ein Fehler. PHP informiert darüber aber nur, wenn man es explizit darum bittet: mit auf E_ALL gestelltem error_reporting. Das ist beim Entwickeln immer empfehlenswert, bekommt man doch damit auch fehlerhafte Zugriffe aufgrund von Schreibfehlern angezeigt. Bevor du also die Prüfungen beginnst:

          $form_error = array();

          Ok, hab ich gemacht und error_reporting hab ich auf E_ALL gestellt. Danke.

          Außerdem ist es besser, statt das Script sterben zu lassen und dabei noch alle Welt mit technischen Details zu behelligen, wenn du im Fehlerfall einen alternativen Weg gehst (if-else) und damit zum einen das Script ordentlich beendest und zum anderen die Fehlermeldung nur an den Administrator leitest.

          Das versteh ich nicht. Wie soll man das script denn ordentlich beenden?
          Meinst Du zum Beispiel anstelle des die() eine neue variable in das error-array schreiben und ausgeben lassen?

          »» else {
          »» $sql = "INSERT INTO agenda (Datum, Zeit, Ort, Adresse) VALUES ('".$_POST['Datum']."', '".$_POST['Zeit']."', '".$_POST['Ort']."', '".$_POST['Adresse']."')";

          Hier fehlt die kontextgerechte Behandlung der Werte. Wenn jemand als Ort D'dorf eingibt, bekommst du nur einen Syntaxfehler. Wenn jemand diese SQL-Injection-Lücke gezielter ausnutzt, ...
          mysql_real_escape_string() heißt das Stichwort.

          Die Behandlung müsste mit der Überprüfung der Eingaben geschehen, oder? (Also direkt vor dem Datenbankeintrag)

          Auch hier wieder: Vor der Schleife sollte $arr explizit als leeres Array angelegt werden. Wenn es nämlich nichts zu Fetchen gibt, wird $arr nicht angelegt und ...

          Thanks!

          »» [code lang=php]<form action="<?php htmlspecialchars($_SERVER['PHP_SELF'])?>" method="post">

          Hier fehlt ein echo.

          Hm, danke... hat aber auch ohne funktioniert?! *kopfkratz

          Besser ist es class zu verwenden. Dass du es hier schon mit "text" belegt hast, macht nichts, class kann man mehrere Werte durch Leerzeichen getrennt zuweisen.

          Danke, das mit dem Leerzeichen wusste ich nicht.

          Und dann möchtest du vielleicht das value-Attribut der input-Elemente mit dem Wert aus der Eingabe vorbelegen, so dass im Falle eines Fehlers in einem Feld der Anwender nicht alles noch einmal einzugeben hat.

          Jap, macht Sinn. Werde ich am Ende noch versuchen hinzuzufügen.

          Für die Syntax-Prüfung kann man einen Regulären Ausdruck verwenden. Dann gibt es aber immer noch die Möglichkeit, ungültige Werte einzugeben wie 25:90. Eine Uhrzeit zu prüfen ist ja noch relativ einfach. Man trennt die Angabe in Einzelwerte und vergleicht auf das Einhalten der Grenzen (für Stunden, Minuten und Sekunden). Prinzipiell kann man das bei einem Datum genauso machen, allerdings ist die Prüfung hier komplexer. Aber PHP macht es einfach, es gibt die Funktion checkdate().

          Die zum Prüfen erzeugten Einzelwerte fügst du bei Fehlerfreiheit mit dem korrekten Trennzeichen so zusammen, wie MySQL sie haben will und fertig ist.

          Ok, da muss ich wohl nochmals über die Bücher, aber werd das in Angriff nehmen, sobald ich den Rest gepackt hab ;).

          Dankeschön
          php-loser

          1. echo $begrüßung;

            Ok, verstanden, aber dann muss ich die Verbindung nochmals neu öffnen wenn ich zur Datenbankabfrage (und dem Auslesen der Tabelle), da die Verbindung nur aufgebaut wird, wenn die Eingaben geprüft und behandelt wurden (und fehlerfrei sind), richtig? Das Auslesen soll ja aber in jedem Fall geschen.

            OK, wenn du auf alle Fälle eine DB-Verbindung brauchst, dann kannst du sie auch ohne die Abhängigkeit von der Prüfung (sprich: am Scriptanfang) öffnen. Dann solltest du aber die Prüfung auf erfolgreiche Verbindung gleich beim Eröffnen einbauen.

            » Außerdem ist es besser, statt das Script sterben zu lassen und dabei noch alle Welt mit technischen Details zu behelligen, wenn du im Fehlerfall einen alternativen Weg gehst (if-else) und damit zum einen das Script ordentlich beendest und zum anderen die Fehlermeldung nur an den Administrator leitest.
            Das versteh ich nicht. Wie soll man das script denn ordentlich beenden?
            Meinst Du zum Beispiel anstelle des die() eine neue variable in das error-array schreiben und ausgeben lassen?

            Ordentlich beenden heißt, dass man auch im Fehlerfall ein vollständiges HTML-Dokument an den Client ausgibt. Die technischen Details der Fehlerursache sind nicht für den Anwender bestimmt. Für den ist es besser, eine Alternative anzubieten, damit er doch noch zu seinem Ziel kommt und nicht zur Konkurrenz rennt.

            » Hier fehlt die kontextgerechte Behandlung der Werte. Wenn jemand als Ort D'dorf eingibt, bekommst du nur einen Syntaxfehler. Wenn jemand diese SQL-Injection-Lücke gezielter ausnutzt, » » mysql_real_escape_string() heißt das Stichwort.
            Die Behandlung müsste mit der Überprüfung der Eingaben geschehen, oder? (Also direkt vor dem Datenbankeintrag)

            Nein, die Überprüfung der Eingabewerte ist ein Thema für sich. Die Behandlung für einen Ausgabekontext ist unabhängig von einer Eingabedatenprüfung und im Ausgabe vorbereitenden Teil am besten aufgehoben. Beispielsweise so:

            $sql = sprintf("INSERT INTO tabelle (feld1, feld2) VALUES ('%s', '%s')",
                mysql_real_escape_string($inhalt_feld1),
                mysql_real_escape_string($inhalt_feld2));

            » »» [code lang=php]<form action="<?php htmlspecialchars($_SERVER['PHP_SELF'])?>" method="post">
            » Hier fehlt ein echo.
            Hm, danke... hat aber auch ohne funktioniert?! *kopfkratz

            Nun ja, ohne echo ergibt das action="" (schau in den HTML-Code, der im Browser ankommt) und das Formular wird an die selbe Ressource gesendet, in der es steht, also an sich selbst.

            echo "$verabschiedung $name";