php_looser: affenformular mit datenbank eingabe und ausgabe

Hi allerseits!

Vielleicht mal als erstes: Ich bin ein PHP-Anfänger und das schon seit eh und je... werds wahrscheinlich auch immer bleiben, aber dennoch geb ich nicht auf wenns drum geht selber was zu basteln.

Allerdings bin ich nun seit ner halben Ewigkeit an folgendem Versuch:

Ich hab für ne Mini-Homepage ein Mini-Administratorenbereich basteln wollen, weil mein Bekannter sich mit HTML garnicht auskennt (und sich auch nich auskennen will)... er soll allerdings auf seiner Seite seine Auftrittsdaten selber aktualisieren können. Dies halt so einfach wie möglich in dem Mini-Administratorenbereich.

Ich hab also versucht mit folgendem Affenformular versucht eine Seite (im Adminbereich) anzuzeigen, welche 1. ein Eingabeformular anzeigt und 2. die Agenda (die Liste mit den Auftritten welche bereits in der DB gespeichert sind). Wenn der Admin den nächsten Auftritt im Formular eingibt und auf Eintragen klickt soll dieses in die Datenbank geschrieben werden und wieder die selbe Seite (inklusiv dem neuen Eintrag) anzeigen.

  
<?php session_start ();  
$connectionid = mysql_connect('localhost', 'root', '');  
$db_selected = mysql_select_db('hobiundroth', $connectionid);  
	  
if (isset ($_POST["Datum"], $_POST["Zeit"], $_POST["Ort"], $_POST["Adresse"])) {  
	if (empty ($_POST["Datum"])) {  
		echo "Bitte alle Felder ausfüllen";  
	}  
	else {  
		$datum = $_POST["Datum"];  
		$zeit = $_POST["Zeit"];  
		$ort = $_POST["Ort"];  
		$adresse = $_POST["Adresse"];  
	}  
  
	if (!$connectionid) {  
		die('Verbindung nicht möglich : ' . mysql_error());  
	}  
  
	if (!$db_selected) {  
    	die ('Kann hobiundroth nicht benutzen : ' . mysql_error());  
	}  
	else {  
		$sql = "INSERT INTO agenda(Datum, Zeit, Ort, Adresse) VALUES ($datum, $zeit, $ort, $adresse)";  
		  
		mysql_query($sql,$connectionid);  
		}  
}  
  
?>  
  
<form action="agenda_form.php" method="post">  
  Datum: <input type="text" name="Datum" size="20"><br>  
  Zeit: <input type="text" name="Zeit" size="20"><br>  
  Ort: <input type="text" name="Ort" size="20"><br>  
  Adresse: <input type="text" name="Adresse" size="20"><br>  
  <input type="submit" value="Hinzufügen">  
</form>  
<?php  
  
if (!$connectionid) {  
		die('Verbindung nicht möglich : ' . mysql_error());  
	}  
  
	if (!$db_selected) {  
    	die ('Kann hobiundroth nicht benutzen : ' . mysql_error());  
	}  
$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>";  
  
?>  

Irgendwie haben die ersten drei Einträge geklappt... Doch nun gehts nicht mehr. Füllt man das Formular aus und klickt auf Eintragen wird einfach die Seite neu geladen... Einträge in der DB werden keine mehr generiert.

Was mach ich falsch?

Danke und liebe Grüsse

PS: auf die Überprüfung der eingegebenen Werte wird vorerst noch verzichtet, da ich erstmal das Grundgerüst zum laufen bringen möchte.

PS2: eine Funktion um Einträge wieder zu löschen sollt ich wohl später auch noch hinzufügen.

  1. echo $begrüßung;

    Ich hab also versucht mit folgendem Affenformular [...]

    Ich seh da kein Affenformular. Dafür fehlen typische Bestandteile eines solchen.

    <?php session_start ();
    $connectionid = mysql_connect('localhost', 'root', '');
    $db_selected = mysql_select_db('hobiundroth', $connectionid);

    Ist es nicht sinvoller, wenn du sogleich auf Fehler prüfst, statt erstmal weiterzumachen und dann erst irgendwann zu prüfen ob die Voraussetzungen für eine Weiterarbeit gegeben sind?
    Wenn die Connection nicht aufgebaut werden konnte, lohnt sich keine Datenbankauswahl.

      $datum = $\_POST["Datum"];  
      $zeit = $\_POST["Zeit"];  
      $ort = $\_POST["Ort"];  
      $adresse = $\_POST["Adresse"];  
    

    Dieses Umkopieren bringt keine Pluspunkte. Du erhöhst damit nur die Komplexität durch zusätzliche Variablen und als Resultat sieht man dem Inhalt nicht mal mehr seine Herkunft als Benutzereingabe an.

    if (!$db_selected) {
         die ('Kann hobiundroth nicht benutzen : ' . mysql_error());
    }
    else {

    Abgesehen davon, dass die() keine Benutzerfreundliche Art ist, auf Fehler zu reagieren, ist das else unnötig. Entweder das Script stirbt wegen eines Fehlers, dann ist alles nachfolgende irrelevant, oder es ist nicht gestorben, dann kommt es zwangsläufig an dem im else stehenden Code vorbei.

      $sql = "INSERT INTO agenda(Datum, Zeit, Ort, Adresse) VALUES ($datum, $zeit, $ort, $adresse)";  
      mysql\_query($sql,$connectionid);  
    

    Und wo ist deine Fehlerbehandlung an der Stelle? Ist das SQL-Statement, das du hier zusammenbaust korrekt? So ohne Anführungszeichen um anzunehmenderweise nicht-nummerische Werte? Und vor allem so ganz ohne kontextgerechte Behandlung der Werte, so dass du dir eine SQL-Injection-Lücke einbaust? Vertraust du etwa auf PHPs Feature Magic Quotes?

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

    Du bist doch schon weiter oben gestorben, wenn die Verbindung nicht da ist. Doppelt sterben zu wollen ist auch nicht besser.

    $q = mysql_query("SELECT Datum, Zeit, Ort, Adresse FROM agenda");
    while($r = mysql_fetch_assoc($q)) {

    PS: auf die Überprüfung der eingegebenen Werte wird vorerst noch verzichtet, da ich erstmal das Grundgerüst zum laufen bringen möchte.

    Eine Inhaltsprüfung ist im Prinzip etwas optionales. Wichtiger ist immer eine kontextgerechte Behandlung wann immer du irgendwelche Werte irgendwo einfügst. Denn die Prüfung soll eigentlich nur fachliche Fehler feststellen. Es bleiben dann immer noch Möglichkeiten mit gewünschten oder ungewünschten Werten sich mindestens Syntaxfehler in SQL-Statements oder HTML-Code oder wo immer du die Werte einfügst einzubauen.

    echo "$verabschiedung $name";

    1. Hallöle,

      $connectionid = mysql_connect('localhost', 'root', '');

      Das ist nicht wirklich Dein ernst, oder?!

      Gruß
      cross

      1. Hallöle,

        »» $connectionid = mysql_connect('localhost', 'root', '');

        Das ist nicht wirklich Dein ernst, oder?!

        Gruß
        cross

        sorry, falsch gepostet - ist natürlich an php_looser gerichtet :)

        Gruß
        cross

      2. echo $begrüßung;

        » $connectionid = mysql_connect('localhost', 'root', '');
        Das ist nicht wirklich Dein ernst, oder?!

        Für eine Testumgebung (davon gehe ich einfach mal aus) ist das zwar auch nicht gerade ideal aber ausreichend.

        echo "$verabschiedung $name";

        1. Hi auch,

          Für eine Testumgebung (davon gehe ich einfach mal aus) ist das zwar auch nicht gerade ideal aber ausreichend.

          Klar ist das ausreichend. Aber Testumgebung hin oder her: Das ist doch eine ganz massive Sicherheitslücke als Root und dann noch ohne Passwort: Weiah :)))

          Gruß
          cross

          1. Hi auch,

            »»
            »» Für eine Testumgebung (davon gehe ich einfach mal aus) ist das zwar auch nicht gerade ideal aber ausreichend.
            »»

            Klar ist das ausreichend. Aber Testumgebung hin oder her: Das ist doch eine ganz massive Sicherheitslücke als Root und dann noch ohne Passwort: Weiah :)))

            Selbst dann ist es Wurst. Der Rechner hängt nicht am Netz. An dem Bastel ich nur und hab mir ne testumgebung mit wampserver eingerichtet.

            Ansonsten danke für die wenig ermunternden Hinweise. Ich gebs wohl endgültig auf. Bin scheinbar wirklich zu dämlich für den schrott...

            machts gut

        2. Hello,

          » $connectionid = mysql_connect('localhost', 'root', '');
          Das ist nicht wirklich Dein ernst, oder?!

          Für eine Testumgebung (davon gehe ich einfach mal aus) ist das zwar auch nicht gerade ideal aber ausreichend.

          Es ist mangelhaft, weil man bereits in der testumgebung die Rechte für den später erfolderlichen User aufbauen sollte. Dieser sollte schließlich nur soviele Rechte haben, wie unbedingt erfoderlich sind.

          Wozu sollte man sich eine testumgebung aufbauen, wenn man diese dann nicht gewissenhaft so aufbaut, dass man das Projekt später einfach übernehmen kann?

          Dazu gehören aber auch die Create-Statements du die Grant-Statements für die Datenbank. Die fehlen immer wieder in Projekten, die ich flicken muss.

          Liebe Grüße aus Syburg bei Dortmund

          Tom vom Berg

          --
          Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
    2. Danke erstmal. Auch wenns ziemlich demütigend auf mich gewirkt hat.
      »»

      Ich seh da kein Affenformular. Dafür fehlen typische Bestandteile eines solchen.

      Selbst wenn es sich um ein Formular handelt, das sich beim absenden wieder selbst aufruft?! dann versteh ich wohl auch den wiki-artikel falsch...

      »» <?php session_start ();
      »» $connectionid = mysql_connect('localhost', 'root', '');
      »» $db_selected = mysql_select_db('hobiundroth', $connectionid);

      »» $datum = $_POST["Datum"];
      »» $zeit = $_POST["Zeit"];
      »» $ort = $_POST["Ort"];
      »» $adresse = $_POST["Adresse"];

      Dieses Umkopieren bringt keine Pluspunkte. Du erhöhst damit nur die Komplexität durch zusätzliche Variablen und als Resultat sieht man dem Inhalt nicht mal mehr seine Herkunft als Benutzereingabe an.

      Das hab ich nur gemacht, weils mir zu mühsahm war beim Eintrag in die Datenbank die immer ein Backslash vor die Anführungs- und Schlusszeichen zu setzen.

      »» if (!$db_selected) {
      »»      die ('Kann hobiundroth nicht benutzen : ' . mysql_error());
      »» }
      »» else {

      Abgesehen davon, dass die() keine Benutzerfreundliche Art ist, auf Fehler zu reagieren, ist das else unnötig. Entweder das Script stirbt wegen eines Fehlers, dann ist alles nachfolgende irrelevant, oder es ist nicht gestorben, dann kommt es zwangsläufig an dem im else stehenden Code vorbei.

      klingt logisch. Wenigstens das versteh ich

      »» $sql = "INSERT INTO agenda(Datum, Zeit, Ort, Adresse) VALUES ($datum, $zeit, $ort, $adresse)";
      »» mysql_query($sql,$connectionid);

      Und wo ist deine Fehlerbehandlung an der Stelle? Ist das SQL-Statement, das du hier zusammenbaust korrekt?

      Das frag ich ja euch. Scheinbar nicht, sonst hätten die Einträge nach klicken des Eintragen-Buttons ja geklappt.

      »» $q = mysql_query("SELECT Datum, Zeit, Ort, Adresse FROM agenda");
      »» while($r = mysql_fetch_assoc($q)) {

      »» PS: auf die Überprüfung der eingegebenen Werte wird vorerst noch verzichtet, da ich erstmal das Grundgerüst zum laufen bringen möchte.

      ich mach meinem namen wohl alle ehre

      1. Hello,

        Ich seh da kein Affenformular. Dafür fehlen typische Bestandteile eines solchen.

        Selbst wenn es sich um ein Formular handelt, das sich beim absenden wieder selbst aufruft?! dann versteh ich wohl auch den wiki-artikel falsch...

        Doch, wenn Dein Script "agenda_form.php" heißt, dann ist es ansatzweise schon ein "Affenformular".

        »» $datum = $_POST["Datum"];
        »» $zeit = $_POST["Zeit"];
        »» $ort = $_POST["Ort"];
        »» $adresse = $_POST["Adresse"];

        Mach es doch so, dass Du Dir einen normierten Buffer für den Datenbankeintrag aufbaust.
        Dieser kann dann später mittels einer (Deiner) Universalfunktion in das Update- oder Insert-Statement überführt werden. Wenn Du dir die einmal erstellst, dann musst Du dann auch nichts mehr händisch unternehmen.

        $_buffer = array(); Array für den MySQL-Eintrag bereitstellen.

        $_buffer ['datum']   = "'".mysql_real_escape_string($_POST["Datum"],$connectionID)."'";
          $_buffer ['zeit']    = "'".mysql_real_escape_string($_POST["Zeit"],$connectionID)."'";
          $_buffer ['ort']     = "'".mysql_real_escape_string($_POST["Ort"],$connectionID)."'";
          $_buffer ['adresse'] = "'".mysql_real_escape_string($_POST["Adresse"],$connectionID)."'";
          $_buffer ['anzahl']  = intval($_POST["Adresse"]);
          $_buffer ['selects'] = 'NULL';

        usw.

        Der Vorteil, dies an dieser Stelle zu tun ist, dass Du genau die Typzuweisung im Blick behältst und an dieser Stelle auch Vorbelegungen und Kontrollen berücksichtigen kannst.

        Kann der Buffer nicht ordentlich gefüllt werden, dann kann das Affenformular bereits hier zur Ausgabe an den Browser zurückkehren und dazu dann wieder die originalen POST-Daten benuten, die natürlich _nicht_ durch magic_quotes verunstaltet sein sollten. Sie müssen dann nur noch in den HTML-Kontext gesetzt werden.

        »» mysql_query($sql,$connectionid);

        hier fehlt die Kontrolle, ob das Query geklappt hat und warum es eventuell schief gegangen ist.

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Mach es doch so, dass Du Dir einen normierten Buffer für den Datenbankeintrag aufbaust.
          Dieser kann dann später mittels einer (Deiner) Universalfunktion in das Update- oder Insert-Statement überführt werden. Wenn Du dir die einmal erstellst, dann musst Du dann auch nichts mehr händisch unternehmen.

          $_buffer = array(); Array für den MySQL-Eintrag bereitstellen.

            $\_buffer ['datum']   = "'".mysql\_real\_escape\_string($\_POST["Datum"],$connectionID)."'";  
            $\_buffer ['zeit']    = "'".mysql\_real\_escape\_string($\_POST["Zeit"],$connectionID)."'";  
            $\_buffer ['ort']     = "'".mysql\_real\_escape\_string($\_POST["Ort"],$connectionID)."'";  
            $\_buffer ['adresse'] = "'".mysql\_real\_escape\_string($\_POST["Adresse"],$connectionID)."'";  
            $\_buffer ['anzahl']  = intval($\_POST["Adresse"]);  
            $\_buffer ['selects'] = 'NULL';  
          

          usw.

          Der Vorteil, dies an dieser Stelle zu tun ist, dass Du genau die Typzuweisung im Blick behältst und an dieser Stelle auch Vorbelegungen und Kontrollen berücksichtigen kannst.

          Kann der Buffer nicht ordentlich gefüllt werden, dann kann das Affenformular bereits hier zur Ausgabe an den Browser zurückkehren und dazu dann wieder die originalen POST-Daten benuten, die natürlich _nicht_ durch magic_quotes verunstaltet sein sollten. Sie müssen dann nur noch in den HTML-Kontext gesetzt werden.

          Dankeschön für Deine Antwort.

          Leider hab ich nichtmal ansatzweise was von dem verstanden was Du mir da erklären wolltest. Ich versuch aber mal irgendwas damit anzufangen. Ich meld mich also so in 50 Stunden wieder, wenn ich damit halbwegs was zu Stande gebracht hab.

          Gruss
          Der dümmste PHP-Schüler der Welt

          1. Hmpf!

            Ok, keine Chance ich verstehs überhaupt nicht. Kann mir da jemand Schritt für Schritt durchhelfen und zwar so einfach wie möglich? Irgendwie muss ichs ja lernen, aber mir hat weder das PHP für Dummies Buch noch das Quake-Tutorial sichtlich weitergeholfen (und ich hab wohlgemerkt beide durchgearbeitet) und mit euren (für mich als totale Niete) bereits relativ komplexen Antworten, kann ich leider nichts anfangen.

            Ich teil das ganze mal in für mich logische Entwicklungs-Schritte auf:

            1. Das Formular erstellen
            2. Überprüfen ob der User das Formular bereits ausgefüllt und gesendet hat.
            3. Die Eingegebenen Daten des Users überprüfen und falls Fehler vorhanden sind das Formular inklusive entsprechender "Fehlermeldung" (z.B. "Kein gültiges Datum") erneut ausgeben
            4. Falls alle Werte die Überprüfung überstanden haben und korrekt sind, die Eingaben in die Datenbank speichern.
            5. Die Ausgabe der Datensätze als Tabelle unter dem Formular

            Ich hoff mal ich hab hier nichts vergessen.

            Zum ersten Schritt:

            <form action="<?php $PHP_SELF ?>" method="post">  
              Datum: <input type="text" name="Datum" size="10"><br>  
              Zeit: <input type="text" name="Zeit" size="5"><br>  
              Ort: <input type="text" name="Ort" size="20"><br>  
              Adresse: <input type="text" name="Adresse" size="20"><br>  
              <input type="submit" value="Hinzufügen">  
            </form>
            

            Irgendwelche Fehler oder Verbesserungsvorschläge (aber bitte dran denken... nix zu komplexes wie das ganze Formular per PHP auszugeben oder was weiss ich)?

            Zum zweiten Schritt:

            if (isset ($_POST["Datum"], $_POST["Zeit"], $_POST["Ort"], $_POST["Adresse"])) {  
            	if (empty ($_POST["Datum"] OR $_POST["Zeit"] OR $_POST["Ort"] OR $_POST["Adresse"])) {  
            		echo "Bitte alle Felder ausfüllen";  
            	}  
            	else {  
            		// Hier folgt Schritt 3  
            	}  
            }
            

            So... sind hier schon irgendwelche Fehler oder ist das ganze sowieso für denn Müll. Wenn ja, was ist daran nicht gut, wie hab ich stattdessen vorzugehen. Wie muss ich das ganze angehen? Vielleicht hab ich ja einfach schon von vornherein einen völlig falschen Denkansatz.

            Zu Schritt 3 Bitte erst kommen wenn ich die ersten zwei Schritte kapiert hab.

            Danke vielmals für eure Geduld und Hilfe!

            1. Hello,

              1. Das Formular erstellen

              Bei Schritt 1. bist Du leider schon zur Hälfte auf dem Holzweg.
              Wenn Du ein aktives Backend gestalten willst, musst Du das Formular nicht erstellen, sondern erstellen lassen :-)
              Was ich damit sagen will ist, dass hier bereits ein Denkschritt vom passiven HTML-Formular zum aktiven (vor-ausgefüllten) HTML-Formular stattfinden muss.

              Selbstverständlich fängt man trotzdem mit dem passiven HTML-Formular an, baut dieses dann aber gleich um zu einer Funktion, die das Formular per PHP erzeugt und mit den eventuell schon vorhandenen Defaults oder den Post-Back-Werten ausfüllt.

              1. Überprüfen ob der User das Formular bereits ausgefüllt und gesendet hat.

              Überprüfen, welche Aktion der User gewünscht hat, also i.d.R. den benutzten Submit-Button feststellen lassen. das fällt unter das Kapitel Steuerflusskontrolle.

              1. Die Eingegebenen Daten des Users überprüfen und falls Fehler vorhanden sind das Formular inklusive entsprechender "Fehlermeldung" (z.B. "Kein gültiges Datum") erneut ausgeben

              lassen!
              Vorhandene Postback-Werte und die Fehlerstati werden der Funktion (als Array) übergeben. Dies kann dieselbe Funktion sein, die bereits in 1. benutzt wurde.

              1. Falls alle Werte die Überprüfung überstanden haben und korrekt sind, die Eingaben in die Datenbank speichern.

              hierzu den Ausgabepuffer aufbauen für die Datenbank, der die Werte so bekommt, dass er sofort durch eine Standardfunktion an die Datenbank ausgeben werden kann. Das SQL-Query kann also automatisiert aus dem Buffer aufgebaut werden.

              1. Die Ausgabe der Datensätze als Tabelle unter dem Formular

              Auch hier irrst Du wieder, denn es ist nicht "das Formular", sondern ein anderes Formular (eine andere Funktion zur Erzeugung der Liste) bzw. eine Kombination aus beiden. Zuvor sollte dann aber die Puffer, aus denen das Eingabeformular und dessen Fehlermeldungen gefüttert werden, wieder zurückgestzt werden auf die Defaults.

              Du hast die Vorgehensweise aber prinzipiell schon genau verstanden und wirst sichlerich innerhalb ein bis zwei Stunden zu den Teilfunktionen kommen und innerhalb weniger Minuten dann zur kompletten Lösung.

              Noch ein Tipp:

              Baue Deine HTML-Ausgaben (Auch die Fehlermeldungen) immer erst als Variablen auf und gebe sie dann erst ganz zum Schluss in einem aktiven Rahmenformular (Template) aus.

              Liebe Grüße aus Syburg bei Dortmund

              Tom vom Berg

              --
              Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
              1. Hi,

                »»...

                Selbstverständlich fängt man trotzdem mit dem passiven HTML-Formular an, baut dieses dann aber gleich um zu einer Funktion, die das Formular per PHP erzeugt und mit den eventuell schon vorhandenen Defaults oder den Post-Back-Werten ausfüllt.

                Und wie funktioniert das?! So?:

                <form action=<?php echo $_SERVER['PHP_SELF']; ?> method="post">  
                  Datum: <input type="text" value="<?php if (isset ($_POST["Datum"])){ echo $_POST["Datum"];} ?>" name="Datum" size="20"><br>  
                  Zeit: <input type="text" value="<?php if (isset ($_POST["Zeit"])){ echo $_POST["Zeit"];} ?>" name="Zeit" size="20"><br>  
                  Ort: <input type="text" value="<?php if (isset ($_POST["Ort"])){ echo $_POST["Ort"];} ?>" name="Ort" size="20"><br>  
                  Adresse: <input type="text" value="<?php if (isset ($_POST["Adresse"])){ echo $_POST["Adresse"];} ?>" name="Adresse" size="20"><br>  
                  <input type="submit" value="Hinzufügen">  
                </form>  
                

                »» 2. Überprüfen ob der User das Formular bereits ausgefüllt und gesendet hat.

                Überprüfen, welche Aktion der User gewünscht hat, also i.d.R. den benutzten Submit-Button feststellen lassen. das fällt unter das Kapitel Steuerflusskontrolle.

                »»

                Ähm... das heisst nun das war falsch?:

                <?php  
                if (isset ($_POST["Datum"], $_POST["Zeit"], $_POST["Ort"], $_POST["Adresse"])) {  
                	if (empty ($_POST["Datum"]) OR empty($_POST["Zeit"]) OR empty($_POST["Ort"]) OR empty($_POST["Adresse"])) {  
                		echo "Bitte alle Felder ausfüllen";  
                	}  
                	else {  
                		// Überprüfung der Eingaben  
                	}  
                }  
                ?>
                

                Wie gesagt würde ich die folgenden Schritte erstmal aussenvor lassen, denn ich tu mich ja schon mit den ersten beiden Schritten so schwer wie ein Fahrradfahrer mit ner 80% Steigung. Nur soviel: Ich hatte Deinen Ausgabepuffer schon im ersten Post nichtmal ansatzweise Verstanden. Ich hätte keine Ahnung was ich damit anfangen sollte.

                Du hast die Vorgehensweise aber prinzipiell schon genau verstanden und wirst sichlerich innerhalb ein bis zwei Stunden zu den Teilfunktionen kommen und innerhalb weniger Minuten dann zur kompletten Lösung.

                Das bezweifle ich stark. Ich sitze schon seit 9Uhr früh an dem Schrott und bin kurz davor mir ne Kugel durch den Schädel zu ballern.

                Baue Deine HTML-Ausgaben (Auch die Fehlermeldungen) immer erst als Variablen auf und gebe sie dann erst ganz zum Schluss in einem aktiven Rahmenformular (Template) aus.

                Bitte was?! Alles per echo ausgeben?! Ist das nicht saumässig umständlich ein ganzes Formular per PHP auszugeben?

                1. Hello,

                  Selbstverständlich fängt man trotzdem mit dem passiven HTML-Formular an, baut dieses dann aber gleich um zu einer Funktion, die das Formular per PHP erzeugt und mit den eventuell schon vorhandenen Defaults oder den Post-Back-Werten ausfüllt.

                  Und wie funktioniert das?! So?:

                  [code lang=php]

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

                  Datum: <input type="text" value="<?php if (isset ($_POST["Datum"])){ echo htmlspecialchars($_POST["Datum"]);} ?>" name="Datum" size="20"><br>

                  usw.

                  Nimm entweder $_SERVER['SCRIPT_NAME'] oder htmlspecialchars($_SERVER['PHP_SELF']), sonst ist Dein Formular duch Cross-Site-Scripting entführbar.

                  Bei der Zuweisung an die Values der Input-Elemente musst Du auch htmlspecialchars() einsetzen, wenn Du  Manipulation des Formulars verhindern willst.

                  Liebe Grüße aus Syburg bei Dortmund

                  Tom vom Berg

                  --
                  Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                  1. Hallo Tom,

                    Nimm entweder $_SERVER['SCRIPT_NAME'] oder htmlspecialchars($_SERVER['PHP_SELF']), sonst ist Dein Formular duch Cross-Site-Scripting entführbar.

                    Bei der Zuweisung an die Values der Input-Elemente musst Du auch htmlspecialchars() einsetzen, wenn Du  Manipulation des Formulars verhindern willst.

                    Ok, danke. Nun steht zwar das Dokument, aber beim Rest hab ich weiterhin keinen Plan wie ich das ganze überhaupt angehen soll. Irgendwie hab ich das Gefühl ich kann eh scripten was ich will, is eh alles falsch. Ich hab nun zwei Stunden vergeblich versucht rauszufinden wie ich denn das in einzelne Module aufgliedern und es schlussendlich zusammenführen muss, aber dabei springen immer nur unendlich komplizierte if-verschachtelungen heraus bei denen ich irgendwann den überblick verlier. Und wie ich die Daten in ein Puffer speichern und von dort aus bearbeiten (auf korrekte Eingabe, special_chars und weiss ich nich was noch alles prüfen) soll hab ich auch mit unzähligen Tutorials nun nicht kapiert.

                    Ich hab mir nun nach unzähligen Stunden an dem für euch total banalen scheiss, den ihr innerhalb von 20minuten gescripted hättet, gedacht ich versuchs besser mal mit nem fertigen Script und hab mich im Internet zu Tode gesucht, aber alles was ich finde ist bereits wieder viel zu komplex mit zu viel schischigaga... ich brauch nur vier felder --> datenbank --> ausgabe. Nich noch tausende nebenfunktionen und weiss ich nich was, aber scheinbar ist das so simple, dass das niemand anbietet.

                    Man, das ist so frustrierend, ich könnt heulen...

                    1. Hello,

                      Man, das ist so frustrierend, ich könnt heulen...

                      und dabei sah doch Dein Ansatz schon ganz brauchbar aus.
                      Ich schau mal, vielleicht baue ich es Dir nachher mal zusammen und füge die entsprechenden Kommentare ein. Du bist schon dicht daran. Aufgeben würde ich also an Deiner Stelle noch nicht.

                      Du könntest aber mal eines machen. Wenn Du für Deine Datenbank den PHPMyAdmin oder sonst ein Tool benutzt, dann könntest Du dich damit mal mit der Datenbank verbinden und dort mal eintippen

                      show create table agenda;

                      und mir das Create-Statement für die Tabelle posten, die Du benutzt. :-)

                      Liebe Grüße aus Syburg bei Dortmund

                      Tom vom Berg

                      --
                      Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
                      1. Hello,

                        »» Man, das ist so frustrierend, ich könnt heulen...

                        und dabei sah doch Dein Ansatz schon ganz brauchbar aus.
                        Ich schau mal, vielleicht baue ich es Dir nachher mal zusammen und füge die entsprechenden Kommentare ein. Du bist schon dicht daran. Aufgeben würde ich also an Deiner Stelle noch nicht.

                        ich wär Dir unglaublich dankbar. Dann wär wenigstens noch ein bisschen was von diesem schrecklichen Sonntag gerettet und evtl. würd ich aus einem fertigen Script mehr lernen als stundenlang ergebnislos zu basteln.

                        Du könntest aber mal eines machen...

                        Das sieht dann etwa so aus:

                        CREATE TABLE agenda (\n  Zeit time NOT NULL default '00:00:00',\n  Ort varchar(24) NOT NULL default '',\n  Adresse text NOT NULL,\n  Datum date NOT NULL default '0000-00-00'\n) ENGINE=InnoDB DEFAULT CHARSET=latin1

                        Aber ich denke mal, selbst das ist alles andere als korrekt. Kannst es gerne ändern.

                        Dankesehr!

                        1. Hello,

                          Das sieht dann etwa so aus:

                          CREATE TABLE agenda (\n  Zeit time NOT NULL default '00:00:00',\n  Ort varchar(24) NOT NULL default '',\n  Adresse text NOT NULL,\n  Datum date NOT NULL default '0000-00-00'\n) ENGINE=InnoDB DEFAULT CHARSET=latin1

                          gibt es einen Grund, warum Du die InnoDB nimmst und nicht MyISAM
                          und warum kein Primary Key in der Tabelle ist?

                          Ohne PK lässt sich eine solche Tabelle später schwer updaten.

                          Liebe Grüße aus Syburg bei Dortmund

                          Tom vom Berg

                          --
                          Nur selber lernen macht schlau
                          http://bergpost.annerschbarrich.de
                          1. gibt es einen Grund, warum Du die InnoDB nimmst und nicht MyISAM
                            und warum kein Primary Key in der Tabelle ist?

                            Öhm... da war eigentlich mal einer... keine Ahnung wieso der nicht mehr drin ist. Wahrscheinlich aus Versehen gelöscht als ich die Infos rausgeholt hab.

                            Das InnoDB ist automatisch generiert...da hab ich keinen Schimmer von.

                            1. Hello,

                              heute hatte ich leider nur kurz Zeit, Deine Frage grundlegend weiterzuverfolgen. Es gab Jobstress :-(

                              Aber ich habe Dich nicht vergessen und versuche es morgen nochmal, nicht zu weit abzuschweifen  :-)
                              Es ist nicht so einfach, sich bei Deiner Frage nicht im Tausendstel zu verlieren, aber das hast Du ja schon bei der Lektüre der Tutorial bemerkt ...

                              Liebe Grüße aus Syburg bei Dortmund

                              Tom vom Berg

                              --
                              Nur selber lernen macht schlau
                              http://bergpost.annerschbarrich.de
                              1. Hi Tom!

                                heute hatte ich leider nur kurz Zeit, Deine Frage grundlegend weiterzuverfolgen. Es gab Jobstress :-(

                                Ja geht mir ähnlich, hab ne 55 Stundenwoche vor mir (bzw. steck mittendrin). Hab dennoch gestern Nacht nochmal versucht daran zu basteln und meine Denkstruktur zu ändern. Weg von Prozessen, hin zu Modulen (Datenbankverbindung, Formular, Eingabeprüfung, Datenaufbereitung, Datenbankhandling). Aber bin nicht sehr weit gekommen. Meine Logik stösst sehr schnell an seine Grenzen wenns dann geht die einzelnen Module wieder miteinander zu verbinden.

                                Aber ich habe Dich nicht vergessen und versuche es morgen nochmal, nicht zu weit abzuschweifen  :-)
                                Es ist nicht so einfach, sich bei Deiner Frage nicht im Tausendstel zu verlieren, aber das hast Du ja schon bei der Lektüre der Tutorial bemerkt ...

                                Jap. Ich meine... funktioniert hat meine erste Lösung ja eigentlich schon. Sie war einfach weit davon entfernt praktikabel zu sein. Ist noch ziemlich schwierig einzusehen, dass etwas das funktioniert "nicht funktioniert" ;).

                                Gruss und Danke

            2. echo $begrüßung;

              Ok, keine Chance ich verstehs überhaupt nicht. [...] und mit euren (für mich als totale Niete) bereits relativ komplexen Antworten, kann ich leider nichts anfangen.

              Bitte beschreibe möglichst genau, wo deine Verständnisprobleme im einzelnen liegen. Bei einem allgmeinen "Ich versteh nix" müsste eine Antwort ebenso umfangreich wie ein Tutorial ausfallen, auf die Gefahr hin, dass du wieder "nix verstehst". Dazu hat verständlicherweise keiner große Lust.

              Ich teil das ganze mal in für mich logische Entwicklungs-Schritte auf:

              Deine Aufteilung ist die Reihenfolge, wie es sich im wesentlichen für einen Anwender darstellt. Für das Script ist eine andere Reihenfolge besser. Jeder Request steht für sich allein. Es gibt für einen Webserver kein Vorher und kein Nachher.

              Dein Script wird also aufgerufen. Dabei kann es sich um einen "normalen" Aufruf per Link oder Adresszeileneingabe oder aber um einen durch ein ausgefülltes Formular ausgelösten handeln. Du prüfst zuerst, ob Formulardaten vorhanden sind. Wenn ja, prüfst du diese und ermittelst die vom User gemachten inhaltlichen Fehler. Gibt es keine, gibst du ein leeres Formular aus ansonsten Fehlermeldungen und das Formular zusammen mit bisher eingegebenen Werten.

              // Variaben immer initialisieren! $errors dient als Sammelstelle für die bei der Prüfung der Eingabewerte anfallenden Fehlermeldungen.
              $errors = array();

              if (!empty($_POST)) { // $_POST ist nicht leer, also wurde das Formular abgesendet
                // Prüfen der Eingabewerte.

              // Die nächsten beiden Zeilen dienen dafür, $_POST['feld1'] bei Nicht-Vorhandensein definitiv zu erzeugen, ansonsten ergeben die weiteren Lesezugriffe darauf E_NOTICE-Meldungen bei aus E_ALL stehendem error_reporting.
                if (!isset($_POST['feld1']))
                  $_POST['feld1'] = '';
                // weitere Prüfungen für $_POST['feld1']
                // bei einem Fehler: $errors[] = 'Fehlermeldungstext';
                // Beispiel:
                if (empty($_POST['feld1']))
                  $errors[] = 'Feld 1 darf nicht leer sein.';

              // Prüfungen der anderen Werte nach dem gleichen Prinzip wie für feld1
              }

              // das Formular war nicht abgeschickt oder es war zwar, enthielt aber Fehler
              if (empty($_POST) or !empty($errors)) {
                // zunächst die Fehlermeldungen ausgeben
                if (!empty($errors)) {
                  echo '<ul class="errors">';
                  foreach ($errors as $error) {
                    echo '<li>', htmlspecialchars($error), '</li>';
                  }
                  echo '</ul>';
                }

              // nun das Formular
                // %s sind Platzhalter. An ihrer Stelle werden die als zweiter bis n-ter Parameter von printf() notierten Werte eingefügt.
                printf('
              <form ...>
                <label for="id_feld1">Feld 1: </label><input type=... name="feld1" id="id_feld1" value="%s">
                <label for="id_feld2">Feld 2: </label><input type=... name="feld2" id="id_feld2" value="%s">
              </form>',
                htmlspecialchars($_POST['feld1']),
                htmlspecialchars($_POST['feld2']));
              }
              else { // Formular war ausgefüllt und das noch dazu fehlerfrei.

              // Datenbankhandling
                // Alle Werte, vor allem die in $_POST, immer mit mysql_real_escape_string() behandeln, bevor sie in ein MySQL-Statement eingefügt werden und auch mit Anführungszeichen einrahmen. Zahlenwerte können ohne Anführungszeichen eingefügt werden, wenn du sicherstellst, dass sie Zahlen und nichts weiter sind, beispielsweise mit intval($wert). Ansonsten stört es auch nicht, wenn eine Zahl in Anführungszeichen notiert und mit mysql_real_escape_string() behandelt wurde.

              }

              Anschließend kommt

              1. Die Ausgabe der Datensätze als Tabelle unter dem Formular

              Wenn du das nur unter bestimmten Bedingungen ausgeben willst, notierst du den Code zu 5. in einem entsprechenden if-Statement.

              echo "$verabschiedung $name";

      2. echo $begrüßung;

        » Ich seh da kein Affenformular. Dafür fehlen typische Bestandteile eines solchen.
        Selbst wenn es sich um ein Formular handelt, das sich beim absenden wieder selbst aufruft?! dann versteh ich wohl auch den wiki-artikel falsch...

        Sich selbst aufzurufen macht daraus noch kein Affenformular. Zum einen ist das Ziel, das Eingabeformular solange anzuzeigen, bis der Anwender keine Fehler mehr in seinen Eingaben hat und dann erst die Daten zu verarbeiten. Und zum anderen sollen die bisherigen Eingaben bei den Wiedervorlagen nicht verloren gehen. Du müsstest also die bisherigen Werte wieder dort eintragen und das natürlich kontextgerecht behandelt (htmlspecialchars()).

        » Dieses Umkopieren [...]
        Das hab ich nur gemacht, weils mir zu mühsahm war beim Eintrag in die Datenbank die immer ein Backslash vor die Anführungs- und Schlusszeichen zu setzen.

        Der Backslash fällt sowieso weg, wenn du deine Daten auf sichere Weise in das SQL-Statement einbinden willst, denn dazu musst du deutlich mehr schreiben als den Backslash. mysql_real_escape_string() sorgt dafür, dass in den Daten enthaltene Zeichen gemäß den Regeln für Strings im (My)SQL-Statement entschärft werden (Maskierung).

        $sql = sprintf('INSERT INTO tabelle (feld1, feld2) VALUES ("%s", "%s")',
          mysql_real_escape_string($_POST['feld1']),
          mysql_real_escape_string($_POST['feld2']));

        » »» $sql = "INSERT INTO agenda(Datum, Zeit, Ort, Adresse) VALUES ($datum, $zeit, $ort, $adresse)";
        » »» mysql_query($sql,$connectionid);
        » Und wo ist deine Fehlerbehandlung an der Stelle? Ist das SQL-Statement, das du hier zusammenbaust korrekt?
        Das frag ich ja euch.

        Also ich hab den Code dafür nicht aus deinem Script entfernt. Es ist deine Aufgabe als Programmierer, die Rückgabewerte der Funktionen auf mögliche Fehlerhinweise zu untersuchen. Für mysql_connect() und mysql_select_db() hast du es ja auch gemacht, wenn auch verbesserungswürdig.

        Wenn du dir mal die Variable $sql ausgibst, wirst du so etwas sehen

        INSERT ... VALUES (2009-03-15, 11:18:03, ortsname, eine_anschrift)

        2009-03-15 sind Zahlen mit einem Subtraktions-Operator dazwischen. MySQL fängt also zu rechnen an. Das ist zwar nicht das was du willst, aber aus Sicht von MySQL ein gültiger Ausdruck. 11:18:03 ist zunächst eine Zahl (11) gefolgt von einem Doppelpunkt. Doppelpunkte kommen aber in der Syntax von MySQL-Statements nicht vor und damit wird das Statement als fehlerhaft abgewiesen. Abgesehen davon sind ortsname und eine_anschrift vermutlich keine Feldbezeichner und reservierte Wörter oder Funktionsnamen schon gar nicht, was die nächsten Fehler wären. Du willst stattdessen einen String, also musst du diesen auch so notieren: in Anführungszeichen (Quotierung).

        echo "$verabschiedung $name";