Ik heb een tabel gemaakt waarbij elke cel een waarde in de database kan updaten. Bijvoorbeeld:

Gebruikersnaam: 1 5 6 8 9 8 5
Gebruikersnaam: 3 6 8 4 5 8 2


Er moet dus per regel/line in de tabel een update op mijn database worden uitgevoerd. Mijn formulier heeft per regel allemaal dezelfde naam dus ik maak al gebruik van name="pos_1[]" en dat update ik met een foreach.

Nou weet ik alleen niet goed hoe ik dit met een heleboel regels moet aanpakken. Ik heb iets gemaakt wat wel werkt maar ik gebruik nu een foreach in een foreach in een foreach etc ...
Ik denk gewoon dat dit niet de goede manier is en tevens duurt het laden van de pagina ook heel lang.

Wie kan mij vertellen hoe dit wel moet?


Dit is mijn formulier:

<?php
// Haal warstats op van openstaande war
	$SQLSelectWarstats = "SELECT warid, gebruikersnaam, positie, pos_1, a_1, a_1_n, pos_2, a_2, a_2_n, a_v, a_v_s
						  FROM warstats
						  WHERE warid = '" . $warid . "'";
	$ResultSelectWarstats = $conn->query($SQLSelectWarstats);
	
	// Sla aantal warleden op in variabel
	$row_count = $ResultSelectWarstats->num_rows;
	
	// Maak een formulier aan en tabel
	echo "<form class='pure-form' method='POST' action='index.php?pagina=war&sub=invullen2'>";
	echo "<legend>War invullen:</legend>";
	echo "<br/>";
	echo "<table class='pure-table invullen'>";
	echo "<thead>";
	echo "<th></th>";
	echo "<th>Gebruikersnaam</th>";
	echo "<th>Positie 1e aanval</th>";
	echo "<th>Sterren 1e aanval</th>";
	echo "<th>Nieuwe sterren 1e aanval</th>";
	echo "<th>Positie 2e aanval</th>";
	echo "<th>Sterren 2e aanval</th>";
	echo "<th>Nieuwe sterren 2e aanval</th>";
	echo "<th>Aantal x verdediging gebruikt</th>";
	echo "<th>Aantal x verdedigd success</th>";
	echo "</thead>";
	echo "<tbody>";
	
	while($warstats = $ResultSelectWarstats->fetch_assoc()) {
		//Hidden post Warid
		echo "<input type='hidden' name='warid' value='" . $warid . "'>";
		echo "<tr>";
		// Warpositie
		echo "<td>" . $warstats["positie"] . "</td>";
		// Gebruikersnaam
		echo "<td>" . $warstats["gebruikersnaam"] . "</td>";
		echo "<input type='hidden' name='gebruikersnaam[]' value='" . $warstats["gebruikersnaam"] . "'>";
		// Tel aantal posities 1e aanval
		echo "<td><select name='pos_1[]'><option></option>";
		foreach (range(1, $row_count) as $number) {
							
			echo "<option>" . $number . "</option>";
							
		}
		echo "</select></td>";
		// Sterren 1e aanval
		echo "<td><select name='a_1[]'><option></option><option>1</option><option>2</option><option>3</option></select></td>";
		// Nieuwe sterren 1e aanval
		echo "<td><select name='a_1_n[]'><option></option><option>1</option><option>2</option><option>3</option></select></td>";
		// Tel aantal posities 2e aanval
		echo "<td><select name='pos_2[]'><option></option>";
		foreach (range(1, $row_count) as $number) {
							
			echo "<option>" . $number . "</option>";
							
		}
		echo "</select></td>";
		// Sterren 2e aanval
		echo "<td><select name='a_2[]'><option></option><option>1</option><option>2</option><option>3</option></select></td>";
		// Nieuwe sterren 2e aanval
		echo "<td><select name='a_2_n[]'><option></option><option>1</option><option>2</option><option>3</option></select></td>";
		// Aantal x verdediging gebruikt
		echo "<td><select name='a_v[]'><option></option><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>6</option><option>7</option><option>8</option><option>9</option><option>10</option></select></td>";
		// Aantal x verdedigd success
		echo "<td><select name='a_v_s[]'><option></option><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option><option>6</option><option>7</option><option>8</option><option>9</option><option>10</option></select></td>";
		echo "</tr>";
		
	}
	
	echo "</tbody>";
	echo "</table>";
	echo "<br/>";
	echo "<input type='submit' name='updaten' value='Bijwerken'>";
	echo "</form>";
?>



En dit wordt zo verwerkt:

<?php
// Maak connectie met db
include ("../connect.php");

// Variabele naar formulier voor redirect
$formpagina = "index.php?pagina=war&sub=invullen";

if (isset($_POST['warid'])) {
	
	foreach ($_POST['pos_1'] as $pos_1) {
		
		foreach ($_POST['a_1'] as $a_1) {
			
			foreach ($_POST['a_1_n'] as $a_1_n) {
				
				foreach ($_POST['pos_2'] as $pos_2) {
					
					foreach ($_POST['a_2'] as $a_2) {
						
						foreach ($_POST['a_2_n'] as $a_2_n) {
							
							foreach ($_POST['a_v'] as $a_v) {
								
								foreach ($_POST['a_v_s'] as $a_v_s) {
									
									foreach ($_POST['gebruikersnaam'] as $gebruikersnaam) {
	
										$SQLUpdateWarstats = "UPDATE warstats
													  SET pos_1='" . $pos_1 . "',
													  a_1='" . $a_1 . "',
													  a_1_n='" . $a_1_n . "',
													  pos_2='" . $pos_2 . "',
													  a_2='" . $a_2 . "',
													  a_2_n='" . $a_2_n . "',
													  a_v='" . $a_v . "',
													  a_v_s='" . $a_v_s . "'
													  WHERE warid='" . $_POST['warid'] . "'
													  AND gebruikersnaam='" . $gebruikersnaam . "'";
										if ($conn->query($SQLUpdateWarstats) === FALSE) {
												
											echo "<div class='error'>MySQL Error 3!! GVD @#$!!!<br/>Raadpleeg een kut beheerder!!</div>"; 
											exit;
																	
										}
										
									}
									
								}
								
							}
							
						}
						
					}
					
				}
				
			}
			
		}
	
	}

	mysqli_close($conn);
	
}
?>
Om hoeveel regels gaat het die je wilt verwerken?

Verder zie ik dat je ook vatbaar bent voor sql injection.
<?php

foreach($_POST['warid'] as $teller => $warid) {

$pos_1 = $_POST['pos_1'][$teller];
$a_1 = $_POST['a_1'][$teller];

// etc
$sql = "UPDATE ... SET ...";

}
?>
Moeten die foreach loops niet onder elkaar komen ipv in elkaar?

Even ter verduidelijking:
5 foreach loops die ieder 5 keer doorlopen worden:
In elkaar 5x5x5x5x5 = 3125 loops.
Onder elkaar 5+5+5+5+5 = 25 loops.

Scheelt nogal...
@ Peter: Alle invoervelden zijn dropdown menu's. Users kunnen dus niet zelf wat intypen. Dan ben ik toch niet vatbaar voor SQL injection??

Maar ik heb het werkend. Thanks mensen:

<?php
if (isset($_POST['warid'])) {
	
	$pos_1_array = $_POST['pos_1'];
	$a_1_array = $_POST['a_1'];
	$a_1_n_array = $_POST['a_1_n'];
	$pos_2_array = $_POST['pos_2'];
	$a_2_array = $_POST['a_2'];
	$a_2_n_array = $_POST['a_2_n'];
	$a_v_array = $_POST['a_v'];
	$a_v_s_array = $_POST['a_v_s'];
	$gebruikersnaam_array = $_POST['gebruikersnaam'];
	
	foreach($_POST['warid'] as $index=>$warid) {
		
		$pos_1 = $pos_1_array[$index];
		$a_1 = $a_1_array[$index];
		$a_1_n = $a_1_n_array[$index];
		$pos_2 = $pos_2_array[$index];
		$a_2 = $a_2_array[$index];
		$a_2_n = $a_2_n_array[$index];
		$a_v = $a_v_array[$index];
		$a_v_s = $a_v_s_array[$index];
		$gebruikersnaam = $gebruikersnaam_array[$index];
	
		$SQLUpdateWarstats = "UPDATE warstats
							  SET pos_1='" . $pos_1 . "',
							  a_1='" . $a_1 . "',
							  a_1_n='" . $a_1_n . "',
							  pos_2='" . $pos_2 . "',
							  a_2='" . $a_2 . "',
							  a_2_n='" . $a_2_n . "',
							  a_v='" . $a_v . "',
							  a_v_s='" . $a_v_s . "'
							  WHERE warid='" . $warid . "'
							  AND gebruikersnaam='" . $gebruikersnaam . "'";
		if ($conn->query($SQLUpdateWarstats) === FALSE) {
												
			echo "<div class='error'>MySQL Error 3!! GVD @#$!!!<br/>Raadpleeg een kut beheerder!!</div>"; 
			exit;
		}
		
	}

	mysqli_close($conn);
	
}
?>
>> Alle invoervelden zijn dropdown menu's. Users kunnen dus niet zelf wat intypen. Dan ben ik toch niet vatbaar voor SQL injection??

Dat is helaas niet zo, ik heb het in een minuut voor elkaar om een waarde te posten die niet in jouw dropdown voorkomt.
"Alle invoervelden zijn dropdown menu's. Users kunnen dus niet zelf wat intypen."

de moeilijke route: hacker maakt een eigen html form met ipv <select> een gewone <input> met dezelfde naam.
Gemakkelijker: klik rechts op de betreffende <select> op het scherm, kies voor inspect in het context menu en pas de values aan naar je keuze.
Volgens mij is dat zelfs zonder extra plugin gewoon aanwezig in Firefox en Chrome.
Allebei bedankt, ik ga de mysqli_real_escape_string toch toepassen dan.
Tevens heb ik inderdaad net zoals Ivo zei via Google chrome een andere waarde in me database toegevoegd terwijl het een dropdown menu is.

Baal er wel van dat dit tegenwoordig kan nu moet ik nog meer checks gaan toepassen. :-(

Maar allebei bedankt voor de support.
Danny von Gaal op 02/11/2015 21:39:14

Allebei bedankt, ik ga de mysqli_real_escape_string toch toepassen dan.
Tevens heb ik inderdaad net zoals Ivo zei via Google chrome een andere waarde in me database toegevoegd terwijl het een dropdown menu is.

Baal er wel van dat dit tegenwoordig kan nu moet ik nog meer checks gaan toepassen. :-(

Maar allebei bedankt voor de support.


In principe kan de normale gebruiker dit niet natuurlijk.

Een optie kan zijn om de waarden die in je dropdown menu voorkomen in te vullen in een tabel in je database. Vervolgens zet je een foreign key op de tabel waar je in wilt vullen.

Welke waarde zet je nu in de database vanuit de dropdown? Een numerieke waarde?

De waardes zijn allemaal numeriek dus ik heb nu wel opgevangen dat letters niet worden toegestaan.

<?php
if (!is_numeric($pos_1)){
			
   echo "<div class='error'>Error: Ingevoerde waardes bevatten letters.</div>";

} else {

}
?>


Maarja daar voorkom ik niet mee dat wanneer 1 t/m 3 is toegestaan iemand er 20 van maakt.
Gelukkig is dit formulier op een adminpagina waar beperkte mensen toegang hebben. Maar ik doe het toch graag meteen goed.

Reageren