guenni
Goto Top

Formulare mit PHP dynamisch erzeugen

Daten aus/in einer MySQL-Tabelle abrufen, ändern oder neu anlegen
mit einem dynamisch erzeugtem Formular

Oftmals sieht man hier Skripte, die ein Formular darstellen,
das von einer Datenbank "gefüttert" wird.

Diese Formulare sind manchmal recht umfangreich und enthalten
eine entsprechende Anzahl von Zeilen wie...

<INPUT type="text" name="email" value="'.$row['email']….usw.

Das ist natürlich einigermaßen umständlich:

Wird die Tabellenstruktur der Tabelle geändert, aus der die Daten stammen,
muß das Formular immer nachgebessert werden.

Schreibfehler können sich einschleichen.

Deshalb hab' ich jetzt mal versucht, die Sache ein bißchen zu vereinfachen.

Das folgende Skript stellt ein Formular dar, das aufgrund einer Tabellenstruktur
erzeugt wird. Das heißt, dass auch nachträglich in die Tabelle eingefügte Spalten
im Formular angezeigt werden, ohne dass man das Formular ändern muß.

Zusätzlich enthält das Formular ein Suchfeld zur Eingabe eines Datensatzes.
Nicht sehr originell, normalerweise würde man einen "Suchbegriff" eingeben,
aber das kann man ja ändern.

efa2d0732a7a76603e1f19c0cd6daafe-unbenannt

Was jeweils im Skript geändert werden muß, ist der Name der Tabelle, was ja mit
der Ersetzen-Funktion eines Editors leicht zu bewerkstelligen ist.

Bei Tabellen ist zu beachten, macht, glaub' ich, sowieso jeder, dass sich die Datensatz-ID
in der ersten Spalte befindet.

Auf Fehler abzufragen, z.B. sind alle Felder ausgefüllt etc., hab' ich jetzt natürlich
verzichtet, um das Skript so kurz wie möglich zu halten.

Heißt, beim Klick auf die Schaltfläche Speichern wird einfach ein leerer Datensatz
eingefügt. Das muß dann jeder selber abfangen.

Verwendete Software:

Linux Debian Sarge
Apache
MySQL
PHP

Das Skript:

// Datei enthält Funktionen zur Datenbankverbindung etc.
include("net-comm/inc/session.inc.php");  
/*
Datensatz suchen:
cmd: Name der Schaltfläche, die angeklickt wurde
Suchen: Value-Eintrag der Schaltfläche
txt_suchen: Name des Textfeldes, in das ein Datensatz eingegeben werden kann
------------------------------------------------------------------
Gesucht wird ein Eintrag, dessen Datensatz-ID mit id übereinstimmt
*/
$cmd=$_POST['cmd'];  
if($cmd=="Suchen"){  
 $id=$_POST['txt_suchen'];  
 $query="select * from tabelle where id=$id";  
 $result=mysql_query($query);
}
/*
Datensatz ändern:
cmd: Name der Schaltfläche, die angeklickt wurde
Ändern: Value-Eintrag der Schaltfläche
HTTP_POST_VARS: Array der übertragenen Formulardaten
data: Array, das die übertragenen Formulardaten aufnimmt
fields: Anzahl der Spaltennamen
-------------------------------------------------------------------
Wenn Daten übertragen wurden, werden sie in der foreach-Schleife
in ein Array übertragen.
Da der Value-Eintrag der Schaltfläche auch übertragen wird, wird das Kopieren
in das Array mit continue unterbunden.
Anschließend wird eine Abfrage abgesetzt, um die Spaltennamen zu ermitteln.
Je nach dem wieviel Spalten ermittelt wurden, werden in der while-Schleife
Updates durchgeführt.
mysql_field_name($result1,$i) enthält jeweils den Spaltennamen,
$data[$i] den Wert, der eingetragen werden soll, where id=".$_POST['id'] bestimmt den Datensatz 
*/
if($cmd=="Ändern"){  
 if($HTTP_POST_VARS){
  foreach($HTTP_POST_VARS as $wert){
   if($wert=="Ändern"){continue;}  
    $data=$wert;
	}
  $query="select * from tabelle";  
  $result1=mysql_query($query);
  $fields=mysql_num_fields($result1);
  $i=1;
  while($i<$fields){
   mysql_query("update tabelle set ".mysql_field_name($result1,$i)." = '$data[$i]' where id=".$_POST['id']) or die("Feld ".mysql_field_name($result1,$i)." wurde nicht aktualisiert");  
	 $i++; 
  }
 }
}
/*
Neuen Datensatz speichern:
cmd: Name der Schaltfläche, die angeklickt wurde
Speichern: Value-Eintrag der Schaltfläche
HTTP_POST_VARS: Array der übertragenen Formulardaten
data: Array, das die übertragenen Formulardaten aufnimmt
valuestring: Enthält die Werte, die gespeichert werden sollen als
Zeichenkette, um sie dem insert-Statement zu übergeben
-----------------------------------------------------------
Die übertragenen Formulardaten werden in ein Array gespeichert.
Dann wird dem Valuestring das zweite Element von data zugewiesen.
Das erste Element wäre das Suchtextfeld, und das ist ja leer bzw. soll ja
nicht abgespeichert werden.
In der for-Schleife werden valuestring nun nacheinander ein Komma und das nächste
Element von data zugewiesen.
Das //echo $query; kann man sich anzeigen lassen, falls der Datensatz nicht gespeichert wird.
Dann sieht man, ob die Abfrage Syntaxfehler enthält.
Die Null im insert-Statement ist ein Platzhalter für die ID des Datensatzes, die ja
automatisch hochgezählt wird und deshalb nicht angegeben werden kann.
*/
if($cmd=="Speichern"){  
 if($HTTP_POST_VARS){
  foreach($HTTP_POST_VARS as $wert){
   if($wert=="Speichern"){continue;}  
    $data=$wert;
	}
	$valuestring="'$data[1]'";  
  for($i=2;$i<count($data)-1;$i++){
   $valuestring.=",'$data[$i]'";  
  }
	$query="insert into tabelle values(0,$valuestring)";  
	//echo $query;
	mysql_query($query) or die("Datensatz konnte nicht gespeichert werden");  
 }
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  

<html>
<head>
<title>Untitled</title>
</head>
<body>
<form action="aleks.php" method="post">  
<table border="1">  
<tr><td colspan="2">  
Datensatz suchen: <input type="text" name="txt_suchen" />  
</td></tr>
<tr><td colspan="2"><hr></td></tr>  
<?
/*
Wenn die Suche nach einem Datensatz erfolgreich war, wird er
im Formular angezeigt.
*/
if($result){
 $row=mysql_fetch_array($result,MYSQL_ASSOC) or die("Keinen passenden Datensatz gefunden");  
 // Zeiger auf Tabellenkopf, der in der while-Schleife mit der Funktion key ausgelesen wird,
 // einmal vorsetzen, da die id nicht geändert werden darf
 next($row);
  while(key($row)){
  echo "<tr><td>".key($row)."</td><td><input type="text" name=".key($row)." value=".$row[key($row)]."></td></tr>";  
 next($row);
 }
/*
Wenn die Suche nicht erfolgreich war bzw. wenn die Seite aufgerufen wird, sind
keine Daten da. Deshalb wird, s.o., eine Abfrage abgesetzt, um die Spaltennamen zu ermitteln
und das Formular aufzubauen
*/
}else{
 $query="select * from tabelle";  
 $result=mysql_query($query);
 $fields=mysql_num_fields($result);
 $i=1;
 while($i<$fields){
  echo "<tr><td>".mysql_field_name($result,$i)."</td><td><input type="text" name=".mysql_field_name($result,$i)."></td></tr>";  
	$i++; 
 }
}
?>
<tr><td align="center" colspan="2">  
<input type="submit" name="cmd" value="Suchen" title="Datensatz suchen(Nr eingeben)">  
<input type="submit" name="cmd" value="Ändern" title="Datensatz ändern">  
<input type="submit" name="cmd" value="Speichern" title="Neuen Datensatz speichern">  
<input type="hidden" name="id" value=<?echo $row[id];?>>  
</td></tr>
</table>
</form>
</body>
</html>

Ich habe mit dem Skript verschiedene Tabellen bearbeitet, hat einwandfrei funktioniert.
Das soll aber jetzt keine Garantie sein.

Wer sich wundert, warum in der Formulardeklaration action="aleks.php" steht:

Inspiriert wurde ich von dem User Aleksander, der immer solche endlosen Formulare postet.

So, jetzt machen wir mal Schluß, ist eh' lang genug.

Grüße
Günni

Content-Key: 59196

Url: https://administrator.de/contentid/59196

Printed on: April 18, 2024 at 23:04 o'clock

Member: StefanHoth
StefanHoth May 28, 2007 at 09:04:54 (UTC)
Goto Top
Hallo,

auch wenn ich diese eigene Lösung ganz nett finde, wollte ich anmerken, dass es im PEAR bereits eine fertige, sehr funktionale Lösung gibt: QuickForm!

Zu finden ist dies unter: http://pear.php.net/package/HTML_QuickForm

Neben einer klassenbasierten Bearbeitung des Formulars (das gesamte Formular ist ein PHP-Objekt) bietet es sowohl eingebaute Filter (zB. trim) als auch beliebige Validierungsregeln.

Für alle, die etwas Zeit zur Einarbeitung mitbringen, lohnt sich der Einsatz auf jeden Fall.

PS: Hier ein paar Tutorials, die mir am Anfang geholfen haben:

(de) http://www.rrze.uni-erlangen.de/dienste/web/php/artikel/html-quickform- ...
(de) http://phpmagazin.de/itr/online_artikel/psecom,id,491,nodeid,62.html
(en) http://www.devarticles.com/c/a/Web-Graphic-Design/Using-HTML-Quickform- ...
Member: Guenni
Guenni May 28, 2007 at 16:45:03 (UTC)
Goto Top
@StefanHoth

Hi,

ich glaube, da hast du etwas mißverstanden. Das sollte keine Lösung
alá QuickForm werden.

Wenn ich eine Tabelle einer Datenbank bearbeiten will, so brauche ich
ja eine Schnittstelle, z.B. ein Formular.

Und wenn ich dieses Formular vorher mit QuickForm kreiere, dann habe ich
ja das, was ich vorher auch hatte: Ich muß für jede Tabelle ein Formular
erstellen, um eine Tabelle zu bearbeiten. Denn jede Tabelle hat ja nun mal
eine unterschiedliche Anzahl von Spalten.

Mein Skript jedoch stellt die Anzahl der Spalten einer Tabelle selber fest, ermittelt
zudem die Namen der Spalten und generiert dann eine entsprechende Anzahl
von Eingabefeldern in einem Formular.

Das Formular wird also automatisch aufgrund der Struktur der Tabelle erstellt, die ich
gerade bearbeiten will(mit Einschränkungen, s.u.). Heißt, auch wenn ich nachträglich
eine Spalte in der Tabelle einfüge / lösche, so wird sie im Formular dargestellt / nicht mehr dargestellt,
ohne dass ich im Skript etwas ändern muß.

Okay, das Tutorial war eine Blitzaktion, sprich, mein Formulargenerator
ist noch etwas "steif". Heißt:

- die erste Spalte einer Tabelle muß id heißen
- es werden nur Textfelder generiert, keine Check-, Radio- oder sonstigen Felder
- die Spaltennamen sollten einem Realwort entsprechen, keine Abkürzung wie spidfgt,
der Spaltenname wird ja im Formular ausgegeben, und da sollte ein Benutzer schon
was mit dem Namen anfangen können

Aber wie gesagt, der Beitrag ist ja ein Tutorial, und das garantiert ja keine endliche
Lösung, sondern es wird lediglich ein Einsprung in eine Materie dargestellt.

Was jemand damit macht, ist seine eigene Sache.

Trotzdem, danke für deinen Kommentar und für die Links.

Grüße
Günni
Member: StefanHoth
StefanHoth May 28, 2007 at 16:53:15 (UTC)
Goto Top
Hallo Günni,

ach so, dann verzeih bitte meinen voreiligen Kommentar.

Wenn Du an soetwas schreibst, solltest Du Dir aber eventuell mal CakePHP (http://cakephp.org/) mit dem Scaffolding-Feature ansehen. Das ist auch so etwas in dieser Richtung.

So long,

Stefan

EDIT: Link added.
Member: Guenni
Guenni May 28, 2007 at 17:03:38 (UTC)
Goto Top
Hi Stefan,

werd' ich mir mal ansehen, wenn ich's finde.

Danke für deine Antwort.

Grüße
Günni
Member: danix
danix Apr 25, 2008 at 19:36:11 (UTC)
Goto Top
Servus Günni,

find dein Script klasse und wollte es einsetzen - geht soweit auch ganz gut aber ich habe noch ein Problem damit. Die Spalten sind beim Eintrag in die Datenbank immer um 1 nach rechts verschoben. Ich werde noch wahnsinnig. Ich vermute dass es mit dem Feld 'txt_suchen' zusammenhängt. Ich habe in meiner html Seite die das Script aufruft ein Feld mit diesem Namen gemacht und übergebe einen leeren Wert weiter der in deinem Script ja dann in der Variable id gespeichert wird. Auch wenn ich nicht weiss was diese Variable mit dem Eintragen Teil zu tun hab bekomme ich ansonsten eine Fehlermeldung wenn ich das nicht mit an die PHP posten lasse. Wenn ich es posten lasse sieht der Text der eingetragen werden soll so aus: values (0,",'text1'........ mir ist nur nicht klar warum das beim Eintragen teil cmd=Schreiben mit dem was zu tun hat. Ich hoffe du kannst mir helfen face-smile

Vielen Dank vorab.
Gruß
Daniel
Member: Guenni
Guenni Apr 28, 2008 at 20:21:38 (UTC)
Goto Top
@danix,

Hi,

ich hab' die Routine zum Speichern nun etwas verändert, obwohl sie ja
funktioniert, zumindest bei den Tabellen in meiner DB.

<?
if($cmd=="Speichern"){  
 if($HTTP_POST_VARS){
  //Die id der Tabelle wird auto. hochgezählt, dafür wird ein Platzhalter erstellt
	$valuestring="0,";  
  foreach($HTTP_POST_VARS as $wert){
   if($wert=="Speichern"){continue;}  
    $data=$wert;
    }
    //$data ist das Suchfeld
    //$data[1] ist die ID
   //Beide werden natürlich nicht gespeichert, deshalb geht es mit $data[2] los
    $valuestring.="'$data[2]'";  
    for($i=3;$i<count($data);$i++){
     $valuestring.=",'$data[$i]'";  
    }
	//Spaltennamen ermitteln und in einer Variablen speichern
	$query="select * from tabelle3";  
  $result=mysql_query($query);
  $fields=mysql_num_fields($result);
	$heads="id";  
  $i=1;
  while($i<$fields){
	 $heads.=",".mysql_field_name($result,$i);  
   $i++;
  }
	
	  $query="insert into tabelle3($heads) values($valuestring)";  
		echo "Folgende Spalten werden mit Werten belegt:<br>";  
		echo $heads."<br>";  
		echo "Eingetragen werden folgende Werte:<br>";  
    echo $valuestring;
    mysql_query($query) or die("Datensatz konnte nicht gespeichert werden");  
		unset($result);
 }
}
?>


Es werden jetzt die Spaltennamen ermittelt und in einer Variablen abgelegt. Somit findet jetzt
eine Zuordnung der Werte zu den richtigen Spalten statt.

Gruß
Günni
Member: Radi1989
Radi1989 Feb 10, 2010 at 09:21:21 (UTC)
Goto Top
Hi Günni,
nach so einem Skript habe ich die ganze Zeit gesucht. Jedoch bin ich noch ziemlich neu hier. Wie müsste denn die session.inc.php aussehen ?

LG