clarpic: Dropdown Auswahl in Datenbank speichern

Liebe Community!

Ich bin nun schon seit 4 Tagen dabei, meine Maturaarbeit fertig zu machen, nur komme ich jezt nicht mehr weiter...
Ich wäre euch sehr dankbar, wenn ihr mir einen neuen Denkanstoß geben könntet.. Ich suche seit gestern im Netz und auch auf dieser Homepage nach einer vermeintlichen Lösung, ich konnte nur noch keine finden. Es kann gut sein, dass ich etwas übersehen habe...

Ich programmiere für meine Maturaarbeit aus Informatik ein Programm, für den Elternsprechtag.
Struktur:
Login
Lehrer & Zeit auswählen
Datenausgabe, Drucken, Ausloggen

Login funktioniert alles perfekt, nur beim Lehrer/Zeit auswählen happerts.

Ich habe ein Dropdown Menü erstellt, das auf eine Tabelle in einer Datenbank zurückgreift. Ich würde jetzt gerne die Auswahl, die ein User machen kann, speichern (entweder Datenbank, in einem Array, oder nur in einer Variable - das ist egal) und die Zeit soll dann nicht mehr vergeen werden können, weil ein Lehrer ja nicht 2 Eltern gleichzeitig bedienen kann.

Hier wäre mein Skript bis jetzt:

<html>  
<head>  
<title>Zeit- und Lehrerauswahl</title>  
</head>  
	<form id="form1" name="Dropdown Auswahl" method="post" action="<?php echo $PHP_SELF; ?>">  
	Lehrer:  
	<select Emp Name='Lehrer'>  
	<option value="">--- Select ---</option>  
	<?php  
  
		session_start();  
  
		include("var.inc.php");  
	  
		$verbindung = mysql_connect($dbserver, $dbuser, $dbpass)  
		or die("Verbindung zur Datenbank konnte nicht hergestellt werden");  
		$select = mysql_select_db($dbname, $verbindung) or die ("Datenbank konnte nicht ausgew&aumlhlt werden");  
		  
		if (isset ($select)&&$select!=""){  
			$select=$_POST ['Lehrer'];  
		}  
  
		$list=mysql_query("select * from lehrer");  
		  
		while($row_list=mysql_fetch_assoc($list)){  
	?>  
			<option value="<?php echo $row_list['ID']; ?>"<?php if($row_list['ID']==$select){ echo "selected"; } ?>>  
			<?php echo $row_list['Name'];?>  
			</option>  
			<?php  
			}  
				mysql_query("INSERT INTO auswahl (Lehrer) VALUES ($_POST ['Lehrer'])");  
			?>  
			  
	</select>  
	</form>  
	  
	<br>  
	<br>  
	  
	<form id="form1" name="Dropdown Auswahl" method="post" action="<?php echo $PHP_SELF; ?>">  
	Zeit:  
	<select Emp Name='Zeit'>  
	<option value="">--- Select ---</option>  
	<?php  
  
		/*session_start();  
  
		include("var.inc.php");  
	  
		$verbindung = mysql_connect($dbserver, $dbuser, $dbpass)  
		or die("Verbindung zur Datenbank konnte nicht hergestellt werden");  
		$select = mysql_select_db($dbname, $verbindung) or die ("Datenbank konnte nicht ausgewählt werden");  
		*/  
		if (isset ($select)&&$select!=""){  
			$select=$_POST ['Zeit'];  
		}  
  
		$list=mysql_query("select * from zeit");  
		  
		while($row_list=mysql_fetch_assoc($list)){  
	?>  
			<option value="<?php echo $row_list['ID']; ?>"<?php if($row_list['ID']==$select){ echo "selected"; } ?>>  
			<?php echo $row_list['Zeit'];?>  
			</option>  
			<?php  
			}  
				mysql_query("INSERT INTO auswahl (Zeit) VALUES ('".$_POST ['Zeit']."')");  
				mysql_close($verbindung);  
			?>  
			  
	</select>  
	<br>  
	<br>  
	<br>  
	  
	<a href='ergebnis.html'>Ausw&aumlhlen</a>  
	  
	</form>  
</body>  
</html>  

meine weitere Überlegung:
Ich habe die Übertragung bereits mit mysql_query("INSERT INTO auswahl (Zeit) VALUES ('".$_POST ['Zeit']."')"); versucht, doch leider klappt das nicht.

Könnt ihr hier einen Fehler in der Anordnung erkennen?

Ich wäre euch sehr dankbar!

LG clarpic

  1. Moin,

    ich bin mir nicht ganz sicher, aber ich glaube nicht, dass du weißt, was du tust. Ich versuche dir mal ein paar Tipps zu geben:

      
    <form id="form1" name="Dropdown Auswahl" method="post" action="<?php echo $PHP_SELF; ?>">
    

    PHP_SELF ist böse. Nimm stattdessen $_SERVER['SCRIPT_NAME'].

    <select Emp Name='Lehrer'>  
      <option value="">--- Select ---</option>
    

    2 Sachen:
      - Was macht das "Emp" im Select-Tag?
      - eine Option, die nicht ausgewählt werden soll, kann man http://de.selfhtml.org/javascript/objekte/elements.htm#disabled@title=disablen

    $select = mysql_select_db($dbname, $verbindung) or die ("Datenbank konnte nicht ausgew&aumlhlt werden");  
      if (isset ($select)&&$select!=""){  
        $select=$_POST ['Lehrer'];  
      }
    

    Du versuchst eine Datenbank zu wählen und schreibst den Ausgang dieses Versuches in eine Variable. Diese wird entweder true oder false enthalten. Dann prüfst du, ob diese boolsche Variable existiert und ob sie ungleich einem leeren String ist. Ist dass der Fall, überschreibst du diese Variable mit einem Element aus dem Post-Array. Mir ist absolut nicht klar, was das bedeuten soll; abgesehen davon ist bei dem Ansprechen des Post-Arrays ein Leerzeichen zuviel.

    while($row_list=mysql_fetch_assoc($list)){  
    ?>  
      <option value="<?php echo $row_list['ID']; ?>"<?php if($row_list['ID']==$select){ echo "selected"; } ?>>  
        <?php echo $row_list['Name'];?>  
      </option>  
    <?php  
    }
    

    Das ist ein sehr waghalsiges Konstrukt, da es den Umgang mit Kontextwechseln unnötig erschwert. Warum gibst du die relevanten Zeilen nicht mit PHP-internen Mitteln, wie echo oder print aus?

      
    mysql_query("INSERT INTO auswahl (Lehrer) VALUES ($_POST ['Lehrer'])");
    

    Jedes Mal, wenn deine Seite aufgerufen wird, schreibst du in eine Tabelle deiner Datenbank einen Datensatz, in dem die Spalte Lehrer mit dem entsprechenden Element des Post-Arrays gefüllt wird. Du prüfst weder, ob überhaupt ein Post-Array existiert, noch ob ein Element mit dem Schlüssel 'Lehrer' existiert. Demzufolge müsstest du entweder einen Fehler bekommen, oder haufenweise leere Datensätze in deiner Tabelle haben.

    Ich habe die Übertragung bereits mit mysql_query("INSERT INTO auswahl (Zeit) VALUES ('".$_POST ['Zeit']."')"); versucht, doch leider klappt das nicht.

    "Klappt nicht" ist keine Fehlerbeschreibung.

    Mein Tipp: Lass dir in deinem Skript alle Fehler, Warnungen und Infos anzeigen, die PHP generiert. Das geht per error_reporting(E_ALL); . Das sind meist ganz vernünftige Meldungen, die du beheben kannst, aber das scheint nicht wirklich dein Problem zu sein. Dein Problem ist eher ein strukturelles. Ich denke nicht, dass du weißt, was das Skript genau macht. Ich empfehle dir ein Konzept aufzumalen, _was_ dein Skript tun soll und _wann_ es es tun soll. Erst danach ist es sinnvoll an die Implementierung zu gehen.

    Grüße Marco

    1. Vielen vielen Dank, Marco!

      Ich verstehe alle deine Vorschlägen und bin dir auch dankbar dafür!
      Mein Script spiegelt glaub ich meine sonst auch komplizierte Denkweise wider.

      Zu deiner Frage: ja, ich bekommme nur leere Einträge in meine Datenbank.
      Ich werde mich gleich nochmal dahinter klemmen!

      Danke und LG! :)

    2. Tach!

      <form id="form1" name="Dropdown Auswahl" method="post" action="<?php echo $PHP_SELF; ?>">
      PHP_SELF ist böse. Nimm stattdessen $_SERVER['SCRIPT_NAME'].

      PHP_SELF ist nicht böse. Böse ist, wenn man manipulierbare Werte (hier durch Anhängen von beliebig geformten Querystrings) ohne Kontextwechselbeachtung ausgibt. Ein htmlspecialchars() drumherum, wenn es nach HTML ausgegeben wird, und PHP_SELF ist genauso ungefährlich wie alles andere. Am besten ist in dem Fall aber, wenn man action="" notiert, dann wird das Formular auch an sich selbst zurückgesendet.

      [HTML-Krams]
          <?php
              session_start();

      Das funktioniert so nicht, zumindest nicht, wenn die Session-ID per Cookie übertragen werden soll. Für das Cookie muss PHP einen Set-Cookie-HTTP-Header senden, und das kann es nicht mehr, wenn bereits eine Ausgabe erfolgt ist - hier in Form von HTML-Code vor dem ersten <?php.

      $select = mysql_select_db($dbname, $verbindung) or die ("Datenbank konnte nicht ausgew&aumlhlt werden");

      if (isset ($select)&&$select!=""){
          $select=$_POST ['Lehrer'];
        }

      
      > Du versuchst eine Datenbank zu wählen und schreibst den Ausgang dieses Versuches in eine Variable. Diese wird entweder true oder false enthalten. Dann prüfst du, ob diese boolsche Variable existiert und ob sie ungleich einem leeren String ist. Ist dass der Fall, überschreibst du diese Variable mit einem Element aus dem Post-Array. Mir ist absolut nicht klar, was das bedeuten soll; abgesehen davon ist bei dem Ansprechen des Post-Arrays ein Leerzeichen zuviel.  
        
      Aus syntaktischer Sicht stört das Leerzeichen nicht, es ist aber eher üblich dort keins zu verwenden. Üblich ist aber \_leider\_ die "or die()"-Fehlerbehandlung. Die ist sehr unschön, weil sie ein halbes Dokument hinterlässt und demjenigen, der sie zu sehen bekommt überhaupt nichts nützt. Besser ist im Falle eines Falles, die Fehlerbedingung abzufragen und das Script auf einem alternativen Weg kontrolliert zu Ende zu bringen. Der Admin sollte einerseits über den Fehler unterrichtet werden, und dem Anwender sollte man eine aus seiner Sicht akzeptable Antwort geben. Dass die Datenbank kaputt ist, intressiert ihn dabei überhaupt nicht, ebensowenig wie irgendwelche anderen internen Details.  
        
      Die Sache mit dem if ist im Zuge des vorangehenden "or die()" sowieso komplett fehl am Platz. $select ist immer true, denn wenn mysql\_select\_db() ein false liefert, stirbt ja das Script. Und das Umkopieren von $\_POST['Lehrer'] nach $select ist nicht nur deswegen sinnlos, weil $select später nicht mehr verwendet wird. Andrerseits sollte das if-Konstrukt korrigiert und noch gemäß dem vorhergehenden Absatz erweitert werden, sowie das "or die()" weggelassen werden - und dies sollte an allen Stellen passieren, an denen "or die()" auftaucht.  
        
      Zudem muss man Umlaute nicht verunstalten, und schon gar nicht indem man dafür unvollständige HTML-Entitys verwendet. Auf alle Fälle sollte man jedoch eine Angabe zur verwendeten Zeichkodierung machen. (Siehe zum Beispiel [Zeichencodierung für Anfänger](http://www.w3.org/International/questions/qa-what-is-encoding.de.php)).  
        
      
      > ~~~php
      
      while($row_list=mysql_fetch_assoc($list)){  
      
      > ?>  
      >   <option value="<?php echo $row_list['ID']; ?>"<?php if($row_list['ID']==$select){ echo "selected"; } ?>>  
      >     <?php echo $row_list['Name'];?>  
      >   </option>  
      > <?php  
      > }
      
      

      Das ist ein sehr waghalsiges Konstrukt, da es den Umgang mit Kontextwechseln unnötig erschwert. Warum gibst du die relevanten Zeilen nicht mit PHP-internen Mitteln, wie echo oder print aus?

      Bitte? Da wird doch alles mit echo ausgegeben, was mit echo ausgegeben werden muss. Und man kann (und sollte) da sehr wohl noch die für die Kontextwechselbeachtung notwendigen Funktionsaufrufe unterbringen. Es ist nicht notwendig, den kompletten HTML-Teil über String-verkettung zusammenzubauen und ihn erst dann auszugeben.

      mysql_query("INSERT INTO auswahl (Lehrer) VALUES ($_POST ['Lehrer'])");
      Jedes Mal, wenn deine Seite aufgerufen wird, schreibst du in eine Tabelle deiner Datenbank einen Datensatz, in dem die Spalte Lehrer mit dem entsprechenden Element des Post-Arrays gefüllt wird. Du prüfst weder, ob überhaupt ein Post-Array existiert, noch ob ein Element mit dem Schlüssel 'Lehrer' existiert. Demzufolge müsstest du entweder einen Fehler bekommen, oder haufenweise leere Datensätze in deiner Tabelle haben.

      Abgesehen vom wieder nicht beachteten Kontextwechsel (diesmal in Richtung SQL, was eine SQL-Injection-Lücke darstellt), ist die gesamte Programmstruktur reichlich fragwürdig. Schon die einfachsten Programmiermuster wie EVA-Prinzip und Affenformular können eine deutliche Verbesserung in die Struktur bringen, womit dann auch die überflüssigen INSERTs von selbst verschwinden.

      Ich habe die Übertragung bereits mit mysql_query("INSERT INTO auswahl (Zeit) VALUES ('".$_POST ['Zeit']."')"); versucht, doch leider klappt das nicht.
      "Klappt nicht" ist keine Fehlerbeschreibung.
      Mein Tipp: Lass dir in deinem Skript alle Fehler, Warnungen und Infos anzeigen, die PHP generiert. Das geht per error_reporting(E_ALL);.

      Dazu noch display_errors einschalten, sonst sieht man selbst die nicht, die jetzt schon hätten zu sehen sein müssen (zum Beispiel wegen session_start()). Die Fehlermeldungen sind aber nur für den Entwicklungsprozess als Bildschirmausgabe sinnvoll. In einem echten produktiv eingesetzten System müsste man sich über das Logging der Meldungen noch ein paar andere Gedanken machen.

      Das sind meist ganz vernünftige Meldungen, die du beheben kannst, aber das scheint nicht wirklich dein Problem zu sein. Dein Problem ist eher ein strukturelles. Ich denke nicht, dass du weißt, was das Skript genau macht. Ich empfehle dir ein Konzept aufzumalen, _was_ dein Skript tun soll und _wann_ es es tun soll. Erst danach ist es sinnvoll an die Implementierung zu gehen.

      Und dabei die EVA-Affen berücksichtigen.

      dedlfix.

      1. Moin,

        Ein htmlspecialchars() drumherum, wenn es nach HTML ausgegeben wird, und PHP_SELF ist genauso ungefährlich wie alles andere.

        Wenn man sich angewöhnt $_SERVER['SCRIPT_NAME'] zu verwenden, braucht man sich nicht um die Lücke, die PHP_SELF darstellt mit extra Funktionen zu schließen.

        Bitte? Da wird doch alles mit echo ausgegeben, was mit echo ausgegeben werden muss.

        Ich habe ja nicht gesagt, dass es falsch ist. In den meisten Editoren ist jedoch die Ausgabe mittels Stringverkettung übersichtlicher (vom Kontextwechsel her) als so ein Konstrukt, zumal man sich Schreibarbeit spart. Ob das nun üblich ist oder nicht: Es war ein Tipp meinerseits.

        Dazu noch display_errors einschalten, sonst sieht man selbst die nicht, die jetzt schon hätten zu sehen sein müssen (zum Beispiel wegen session_start()).

        Richtig. Sollte man auf die Grundeinstellungen keinen Zugriff haben, ließe sich selbige auch für die Script-Laufzeit mit ini_set() einstellen.

        Grüße Marco

        1. Tach!

          Ein htmlspecialchars() drumherum, wenn es nach HTML ausgegeben wird, und PHP_SELF ist genauso ungefährlich wie alles andere.

          Wenn man sich angewöhnt $_SERVER['SCRIPT_NAME'] zu verwenden, braucht man sich nicht um die Lücke, die PHP_SELF darstellt mit extra Funktionen zu schließen.

          Du musst sowieso bei jeder HTML-Ausgabe den Kontextwechsel beachten. Außerdem ist SCRIPT_NAME nicht in allen Fällen passend (Rewriting). Was spricht denn gegen das Leerlassen des Action-Attributs? Kein Einfügen, kein Kontextwechsel, noch nicht mal ein Funktionsverlust.

          Bitte? Da wird doch alles mit echo ausgegeben, was mit echo ausgegeben werden muss.
          Ich habe ja nicht gesagt, dass es falsch ist. In den meisten Editoren ist jedoch die Ausgabe mittels Stringverkettung übersichtlicher (vom Kontextwechsel her) als so ein Konstrukt, zumal man sich Schreibarbeit spart. Ob das nun üblich ist oder nicht: Es war ein Tipp meinerseits.

          Und ich tippte dagegen. Für mich wird es nicht übersichtlicher, wenn der Editor alles als String einfärbt und die HTML-Teile nicht weiter hervorhebt. Etwas mehr Tipparbeit spart man sich mit der Verwendung von <?= statt <?php echo. Ab PHP 5.4 ist das stets verfügbar, vorher nur wenn short_open_tag angeschaltet ist. - Letzlich ist es Geschmackssache, ob man Stringverknüpfung oder mit Komma getrennte echo-Parameter verwendet oder PHP als Template-Sprache ansieht, in der man nur die notwendigen variablen Teile mit PHP-Code ausgibt.

          dedlfix.