Problem beim Ändern mehrerer MySQL Daten in einem Formular

blubberblase

Mitglied
Guten Abend!
Ich möchte gerne Daten aus einer MySQL DB auslesen und pro Zeile einen Eintrag bearbeiten können. Dieser Eintrag enthält nur eine Zahl, welche dann als spätere Sortierung dient. Ich gehe alle Einträge der Datenbank durch und gebe sie in einer Tabelle aus. Das zu editierende Feld ist beschreibbar. Klicke ich nun auf den Update Button, erhalte ich wieder die Tabelle ohne jegliche Änderung. Lediglich die letzte Zeile wird gespeichert.

Das Auslesen ist nicht das Problem, aber das Ändern. Hier ist der Code:

PHP:
<?php
$sortieren = $_GET["sortieren"]; 
$mysqlhost="...";
$mysqluser="...";
$mysqlpwd="...";
$mysqldb="...";


$connection=mysql_connect($mysqlhost, $mysqluser, $mysqlpwd) or die ("Verbindungsversuch fehlgeschlagen");
 
mysql_select_db($mysqldb, $connection) or die("Konnte die Datenbank nicht waehlen.");
 
$sql = "SELECT id, sort, firstname, lastname, text FROM jos_cdtastymonials ORDER BY sort DESC";
 
$monials = mysql_query($sql) or die("Anfrage nicht erfolgreich");
 
$anzahl = mysql_num_rows($monials);
 
echo "Anzahl der Datensaetze: $anzahl";
 
if ($sortieren == "submit") { 
    // Überprüfe Angaben
    if ($Fehler != 1) {
		while ($adr = mysql_fetch_array($monials)){
        	$sql2 = "UPDATE jos_cdtastymonials SET sort= '".$_POST['sort']."' WHERE ID = '".$_POST['id']."'";
        	mysql_query($sql2) OR die(mysql_error());
		}
		
        echo "Deine Angaben wurden bearbeitet.";
    }
}
 
 
?>
<form action="sortierung_3.php?sortieren=submit" method="POST">
<table cellpadding="1" cellspacing="3" border="1">
<tr>
<td>ID</td>
<td>Sortierung</td>
<td>Vorname</td>
<td>Nachname</td>
<td>Bewertung</td>
</tr>
 
<?php
while ($adr = mysql_fetch_array($monials)){
?>
 
<tr>
<td><input id="id" type="text" name="id" maxlength="4" size="4" value="<?=$adr['id']?>"></td>
<td><input id="sort" type="text" name="sort" maxlength="4" size="4" value="<?=$adr['sort']?>"></td>
<td><?=$adr['firstname']?></td>
<td><?=$adr['lastname']?></td>
<td><?=$adr['text']?></td>
</tr>
 
<?php
}
?>
 
</table>
<input type="submit" name="submit" value="Update DB">
</form>

Ich denke im UPDATE Teil muss der Wurm drin sein. Pro Zeile kann ich ja den Sort Eintrag ändern. Nun müsste ich dem UPDATE Befehl ja mitteilen, dass er alle Zeilen durchgehen soll - aber wie?

Ich hab das auch schon mit einem Array versucht: Also das ich dem Inputfeld für sort den Namen sort[<?=$adr['id']?> gebe und die While Schleife durch

PHP:
foreach ($_POST['sort'] as $id => $sort) {
    $sql = "UPDATE jos_cdtastymonials SET sort='$sort' WHERE ID='$id'";
    mysql_query($sql) OR die(mysql_error());
}

ersetze...Das hätte den Vorteil, dass das Array der Sortierungswerte dann gleich mit den IDs indiziert ist...aber leider funktioniert das noch weniger :).

Hat jemand eine Idee, Tipps oder sonstiges parat, damit ich das Teil zum Laufen bekomme?
Danke für Eure Hilfe!

Grüße
 
Erstmal drei Dinge bezüglich Sicherheit und Programmierstil:
  • Du verwendest die $_POST-Daten einfach so in deinem SQL-Query ==> SQL Injection.
    Durch bestimmte Inhalte dieser Daten kann zum Teil deine ganze Datenbank gelöscht werden!

    Nutze also bitte [phpf]mysql_real_escape_string[/phpf]:
PHP:
$_POST['sort'] = mysql_real_escape_string($_POST['sort']);


Siehe dazu auch mein Tutorial: Sicherheit in PHP-Codes schaffen

  • Du greifst auf "sortieren" im $_GET-Array zu. Dieser Eintrag könnte eventuell (beim ersten Aufruf zum Beispiel) nicht existieren.
    Wenn [phpf]error_reporting[/phpf] mindestens auf E_NOTICE gestellt ist, dann bekommst du auch Hinweise seitens PHP zu Gesicht.
    Zu Empfehlen ist folgendes:
PHP:
$sortieren = ( isset($_GET['sortieren']) ? $_GET['sortieren'] : 0 );
Also wenn der Eintrag existiert, nehme diesen Wert, ansonsten 0.
  • Bei der Ausgabe der Datensätze würde ich noch htmlspecialchars($var, ENT_QUOTES); einbauen, damit eventuelle Anführungszeichen nicht das value-Attribut des Textfeldes schließen und dann eventuelles HTML interpretiert wird.
    Dies kann auch zu "bösen" Zwecken genutzt werden.

Nun zu deinem Problem:
So wie ich das sehe, gibst du für jeden Datensatz zwei input-Felder mit gleichem Namen (und zwar "id" und "sort") aus. Das kann so nicht direkt funktionieren.
Denn die Werte werden immer überschrieben => Deshalb nur letzter Wert/letzte Zeile verfügbar

Ich würde dir folgendes empfehlen:
PHP:
<input id="id" type="text" name="id[]" maxlength="4" size="4" value="<?=$adr['id']?>">
<input id="sort" type="text" name="sort[]" maxlength="4" size="4" value="<?=$adr['sort']?>">
So ist $_POST['sort'] ein Array mit allen Werten.

(Übrigens vergibst du auch immer die gleiche ID, dies stellt für das Formular und dessen Verarbeitung kein Problem dar, ist aber auch nicht gültiges HTML!)

Und dann im PHP-Code:
PHP:
$count = count($sort_arr);

for ($i=0; $i<$count; $i++)
{
  // Ist die Spalte ID vom Typ Integer? Dann keine Anführungszeichen!
  $update_sql = "UPDATE jos_cdtastymonials SET sort='". $sort_arr[$i] . "' WHERE ID=".$id_arr[$i];
}

Vorher natürlich noch alle Werte entschärfen und prüfen!
 
@ComFreek: Wow, danke für deinen lehrreichen Beitrag! Das mit der Sicherheit und meinem Programmierstil gibt mir wirklich zu denken. Da muss ich unbedingt nachbessern. DANKE :)

Ich habe mal versucht deine Anmerkungen zum Programm umzusetzen, allerdings habe ich da sicherlich einiges übersehen....also das ist der neue Code:

PHP:
<?php
$sortieren = (isset($_GET['sortieren']) ? $_GET['sortieren'] : 0 );
$mysqlhost="";
$mysqluser="";
$mysqlpwd="";
$mysqldb="";


$connection=mysql_connect($mysqlhost, $mysqluser, $mysqlpwd) or die ("Verbindungsversuch fehlgeschlagen");
 
mysql_select_db($mysqldb, $connection) or die("Konnte die Datenbank nicht waehlen.");
 
$sql = "SELECT id, sort, firstname, lastname, text FROM jos_cdtastymonials ORDER BY sort DESC";
 
$monials = mysql_query($sql) or die("Anfrage nicht erfolgreich");
 
$anzahl = mysql_num_rows($monials);

//$_POST['sort'] = mysql_real_escape_string($_POST['sort']); 
 
echo "Anzahl der Datensaetze: $anzahl";
 
if ($sortieren == "submit") { 
    // Überprüfe Angaben
    //if ($Fehler != 1) {
		$count = count($sort_arr);

		for ($i=0; $i<$count; $i++)
		{
			// Ist die Spalte ID vom Typ Integer? Dann keine Anführungszeichen!
  			$update_sql = "UPDATE jos_cdtastymonials SET sort='$sort_arr[$i]' WHERE ID='$id_arr[$i]'";
  			 mysql_query($update_sql) OR die(mysql_error());
		}  
		
        echo "Deine Angaben wurden bearbeitet.";
   // }
}
 
?>
<form action="sortierung_3.php?sortieren=submit" method="POST">
<table cellpadding="1" cellspacing="3" border="1">
<tr>
<td>ID</td>
<td>Sortierung</td>
<td>Vorname</td>
<td>Nachname</td>
<td>Bewertung</td>
</tr>
 
<?php
while ($adr = mysql_fetch_array($monials)){
?>
 
<tr>
<td><input type="text" name="id[]" maxlength="4" size="4" value="<?=$adr['id']?>"></td>
<td><input type="text" name="sort[]" maxlength="4" size="4" value="<?=$adr['sort']?>"></td>
<td><?=$adr['firstname']?></td>
<td><?=$adr['lastname']?></td>
<td><?=$adr['text']?></td>
</tr>
 
<?php
}
?>
 
</table>
<input type="submit" name="submit" value="Update DB">
</form>

Irgendwie hat die Variable $sort_arr und $id_arr ja gar keine Verknüpfung mit dem Rest :) ?
 
$sort_arr und $id_arr sollen die Arrays aus $_POST['sort'] und $_POST['id'] sein.
Sorry hatte ich oben nicht erwähnt, ich dachte es geht aus dem Namen hervor ;)

Also fügst du in den IF-Block folgendes hinzu:
PHP:
$sort_arr = isset($_POST['sort']) ? $_POST['sort'] : die('Error');
$id_arr = isset($_POST['id']) ? $_POST['id'] : die('Error');
(Ich habe es hier mit der Fehlerbehandlung sehr einfach gehalten. Natürlich kann man das weiter ausbauen - von der Email an den Administrator bis hin zu Exceptiones)

Und in der Schleife musst du auch unbedingt die Werte von $sort_arr mittels [phpf]mysql_real_escape_string[/phpf] entschärfen.
Bei $id_arr solltest du mittels [phpf]is_numeric[/phpf] prüfen, ob der Wert auch wirklich eine Zahl ist, wenn ja dann via [phpf]intval[/phpf] in einen Integer konvertieren.
Ansonsten nichts machen, da [phpf]intval[/phpf] einen String ohne Zahlen zu 0 verwandelt, kann es vorkommen, dass falsche Datensätze bei "menschlichen Fehlern" aktualisiert werden.

Wobei ich mich sowieso wundere wieso du die Änderung von dem ID-Attribut zulässt. Normalerweise soll sich der Primärschlüssel (davon gehe ich jetzt aus) nicht verändert werden!

Zurück zum Entschärfen der Daten:

Einmal in der Schleife:
PHP:
for ($i=0; $i<$count; $i++) 
{ 
  $sort_arr[$i] = mysql_real_escape_string($sort_arr[$i]);
  
  if ( !is_numeric($id_arr[$i]) ) // falsche ID-Werte überspringen
    continue;
  
  $id_arr[$i] = intval($id_arr);

  $update_sql = "UPDATE jos_cdtastymonials SET sort='$sort_arr[$i]' WHERE ID=$id_arr[$i]"; 
  mysql_query($update_sql) OR die(mysql_error()); 
}
Du kannst aber auch z.B. folgendes nehmen:
PHP:
array_walk($sort_arr, function(&$value, $key)
{
  $value = mysql_real_escape_string($value);
});

array_walk($id_arr, function(&$value, $key)
{
  if ( !is_numeric($value) )
    throw new ErrorException('ERROR!');
  $value = intval($value);
});
 
Hey ComFreek! Mensch, Danke für deine weiteren Tipps! Hm, irgendwie dachte ich schon dran, dass es sich darauf bezieht, aber meine Versuche das dann zum Laufen zu bekommen scheiterten :)

Leider funktionieren deine neuen Änderungsvorschläge nicht. Ich erhalte immer "Error" als Meldung und danach kommt nichts mehr. Entferne ich
PHP:
 ? $_POST['sort'] : die('Error')
und
PHP:
? $_POST['id'] : die('Error')
dann lädt er zumindest die Tabelle weiter und der "Error" ist weg.

Leider lassen sich aber da auch keine Einträge ändern. Das mit der änderbaren ID muss ich noch entfernen. Das war nur ein Test :)

Hat er irgendwie Probleme die Werte zu bekommen *grübel* Wenn ich
PHP:
$_POST['sort'] = mysql_real_escape_string($_POST['sort']);
aktiviere, bekomme ich auch eine Fehlermeldung mit Notice: Undefined index: sort.

Hier ist noch mal die komplette Änderung:

PHP:
<?php
$sortieren = (isset($_GET['sortieren']) ? $_GET['sortieren'] : 0 );
$mysqlhost="";
$mysqluser="";
$mysqlpwd="";
$mysqldb="";

echo error_reporting(E_ALL);
$connection=mysql_connect($mysqlhost, $mysqluser, $mysqlpwd) or die ("Verbindungsversuch fehlgeschlagen");
 
mysql_select_db($mysqldb, $connection) or die("Konnte die Datenbank nicht waehlen.");
 
$sql = "SELECT id, sort, firstname, lastname, text FROM jos_cdtastymonials ORDER BY sort DESC";
 
$monials = mysql_query($sql) or die("Anfrage nicht erfolgreich");
 
$anzahl = mysql_num_rows($monials);

//$_POST['sort'] = mysql_real_escape_string($_POST['sort']); 
 
echo "Anzahl der Datensaetze: $anzahl";

if ($sortieren == "submit") {  
    
    //if ($Fehler != 1) {
    	        $sort_arr = isset($_POST['sort']) ? $_POST['sort'] : die('Error');
		$id_arr = isset($_POST['id']) ? $_POST['id'] : die('Error');  
		$count = count($sort_arr);
		for ($i=0; $i<$count; $i++) 
		{ 
			//$sort_arr[$i] = mysql_real_escape_string($sort_arr[$i]);
  
			if ( !is_numeric($id_arr[$i]) ) // falsche ID-Werte überspringen
			continue;
  
			$id_arr[$i] = intval($id_arr);

			$update_sql = "UPDATE jos_cdtastymonials SET sort='$sort_arr[$i]' WHERE ID='$id_arr[$i]'"; 
  			mysql_query($update_sql) OR die(mysql_error()); 
		}  		
        echo "Deine Angaben wurden bearbeitet.";
    //}
}
 echo error_reporting(E_ALL);
?>
<form action="sortierung_3.php?sortieren=submit" method="POST">
<table cellpadding="1" cellspacing="3" border="1">
<tr>
<td>ID</td>
<td>Sortierung</td>
<td>Vorname</td>
<td>Nachname</td>
<td>Bewertung</td>
</tr>
 
<?php
while ($adr = mysql_fetch_array($monials)){
?>
 
<tr>
<td><input type="text" name="id[]" maxlength="4" size="4" value="<?=$adr['id']?>"></td>
<td><input type="text" name="sort[]" maxlength="4" size="4" value="<?=$adr['sort']?>"></td>
<td><?=$adr['firstname']?></td>
<td><?=$adr['lastname']?></td>
<td><?=$adr['text']?></td>
</tr>
 
<?php
}
?>
 
</table>
<input type="submit" name="submit" value="Update DB">
</form>
 
Zuletzt bearbeitet:
Solle eigentlich funktionieren :/

Schreibe mal ganz an den Anfang des Skriptes:
PHP:
var_dump($_POST, $_GET);
und poste die Ausgaben.
 
Beim ersten Aufrufen des Skriptes ohne Query String sollte dies ja stimmen!

Poste auch die Ausgabe, nachdem du auf den Submit-Button geklickt hast!
 
Ok, hier ist die Ausgabe nach dem ich Submit gedrückt habe:

Code:
array(3) { ["id"]=> array(27) { [0]=> string(2) "49" [1]=> string(2) "51" [2]=> string(2) "71" [3]=> string(2) "72" [4]=> string(2) "64" [5]=> string(2) "65" [6]=> string(2) "73" [7]=> string(2) "74" [8]=> string(2) "75" [9]=> string(2) "76" [10]=> string(2) "77" [11]=> string(2) "78" [12]=> string(2) "79" [13]=> string(2) "80" [14]=> string(2) "82" [15]=> string(2) "83" [16]=> string(2) "84" [17]=> string(2) "85" [18]=> string(2) "86" [19]=> string(2) "87" [20]=> string(2) "88" [21]=> string(2) "91" [22]=> string(2) "92" [23]=> string(2) "93" [24]=> string(2) "94" [25]=> string(2) "95" [26]=> string(2) "96" } ["sort"]=> array(27) { [0]=> string(1) "0" [1]=> string(1) "0" [2]=> string(1) "0" [3]=> string(1) "0" [4]=> string(1) "0" [5]=> string(1) "0" [6]=> string(1) "0" [7]=> string(1) "0" [8]=> string(1) "0" [9]=> string(1) "0" [10]=> string(1) "0" [11]=> string(1) "0" [12]=> string(1) "0" [13]=> string(1) "0" [14]=> string(1) "0" [15]=> string(1) "0" [16]=> string(1) "0" [17]=> string(1) "0" [18]=> string(1) "0" [19]=> string(1) "0" [20]=> string(1) "0" [21]=> string(1) "0" [22]=> string(1) "0" [23]=> string(1) "0" [24]=> string(1) "0" [25]=> string(1) "0" [26]=> string(1) "0" } ["submit"]=> string(9) "Update DB" } array(1) { ["sortieren"]=> string(6) "submit" }

Dafür musste ich aber einiges auskommentieren:
PHP:
//$sort_arr[$i] = mysql_real_escape_string($sort_arr[$i]);
//$_POST['sort'] = mysql_real_escape_string($_POST['sort']);

und das

PHP:
$sort_arr = isset($_POST['sort']); //? $_POST['sort'] : die('Error');
$id_arr = isset($_POST['id']); //? $_POST['id'] : die('Error');
so auskommentieren, damit ich überhaupt die Möglichkeit habe mir das anzeigen zu lassen. Sonst lädt er die Tabelle und den Button nicht.
 

Neue Beiträge

Zurück