de.comp.lang.php FAQ

11.7. Wie kann ich aus einer Datenbanktabelle einen <select> erzeugen?

Keywords: select | Formular | LOV | option | Auswahlfeld | Liste | Menue | HTML

Antwort von Kristian Köhntopp

Aus einer Datenbanktabelle mit einer List Of Values (LOV) soll eine Selectbox erzeugt werden:

<?php
/*
 * lovselection - turn a list of values table from a database
 *                into a html option list.
 *
 * (requires DB_Sql subclass from PHPLIB)
 *
 * by Kristian Köhntopp
 *
 */

function lovselection($classname, $table, $field, $oldvalue) {
  $ret = "";
  $db  = new $classname;

  $query = sprintf("select %s from %s",
             $field,
             $table
           );
  $db->query($query);
  while($db->next_record()) {
    if ($db->f("field") == $oldvalue)
      $selected = " selected";
    else
      $selected = "";

    $ret .= sprintf("<option%s>%s</option>\n",
              $selected,
              $db->f($field)
            );
  }

  $db->free();
  return $ret;
}

/*
 * is_validlov - check if a given value is valid according
 *               to a given list of values
 *
 * by Kristian Köhntopp
 *
 */
function is_validlov($classname, $table, $field, $value) {
  $db = new $classname;

  $query = sprintf("select %s from %s where %s = '%s'",
             $field,
             $table,
             $field,
             addslashes($value) // value from outside
                                // is potentially dangerous!
           );
  $db->query($query);
  if ($db->num_rows() == 1) {
    $db->free();
    return true;
  } else {
    $db->free();
    return false; // 0 or 2+ answers are a failure!
  }
}

?>

<!-- Formularfragment -->
<select name="f_ortsnetz" size="1">
<?php echo lovselection("DB_Example", "ortsnetze", "vorwahl", $ortsnetz) ?>
</select>


<!-- Auswertefragment -->
<?php
if (is_validlov("DB_Example", "ortsnetze", "vorwahl", $f_ortsnetz))
  $ortsnetz = $f_ortsnetz; // value is valid
else {
  $error["ortsnetz"] = "Das angegebene Ortsnetz ist ungültig.";
  $ortsnetz = ""; // clear session variable
}
?>

Die Funktion lovselection() generiert aus einer Tabelle von Werten in der Datenbank (eine sogenannte List Of Values, LOV) eine Reihe von Option-Tags. Man kann dann leicht den passenden Select-Container drumwickeln. lovselection() verwendet die Datenbank-Klasse von PHPLIB, läuft also mit prinzipiell jeder SQL-Datenbank.

Wenn man einen solchen Select-Tag generiert, dann heißt das natürlich nicht, dass das so erzeugte Formular on Submit ausschließlich Werte zurückliefert, die man dort zur Auswahl gestellt hat. Stattdessen kann jeder beliebige Wert zurück kommen.

Es ist also notwendig, dass man ein Prädikat erzeugt, das überprüft, ob der eingegangene Wert gültig ist. Dieses Prädikat ist is_validlov(): Die Funktion liefert true, wenn der gegebene Wert genau einmal in der angegebenen Tabelle vorkommt.

Im Beispiel kann mit der Variablen $f_ortsnetz, die aus dem Formular kommt, nicht gearbeitet werden - sie kann potentiell ungültige Werte ("003432") enthalten oder sogar potentiell gefährliche Werte ("0431' or sp_clearall() or '0431", wobei sp_clearall() irgendeine Einbaufunktion oder Stored Procedure in einer Datenbank ist, die gefährliche Dinge mit der Datenbank macht).

Der Wert von $f_ortsnetz kann nach $ortsnetz kopiert und gefahrlos verwendet werden genau dann und nur dann, wenn is_validlov() wahr ist, denn dann kommt der Inhalt von $f_ortsnetz genau einmal in der angegebenen Tabelle vor und ist damit eine gültige und garantiert harmlose Auswahl.

Die Funktion is_validlov() selbst kann sich den Luxus nicht erlauben, mit harmlosen Werten zu arbeiten und muss daher so geschrieben sein, dass sie auch mit gefährlichen Inhalten in $value zurecht kommt. Ein - noch recht schwacher, aber einigermassen allgemeingültiger - Versuch, dies zu gewährleisten ist die Anwendung von addslashes() bevor der Wert von $value in das SELECT-Statement eingesetzt wird. Besser wäre es, könnte man Annahmen ueber das Aussehen von $value machen (keine Spaces, keine Single Quotes, keine Backslashes, ...) und würde man dann mit preg_match() abtesten, ob $value so aussieht, wie man erwartet, bevor man den Wert in das SELECT-Statement einsetzt.

hosted by
schlund + partner

Valid HTML 4.01! Valid CSS!

11.7. Wie kann ich aus einer Datenbanktabelle einen <select> erzeugen?
http://www.dclp-faq.de/q/q-formular-select.html
de.comp.lang.php FAQ | (c) Copyright 2000-2003 Das dclp-FAQ-Team