Foreach Listbox laatste entry dubbel
Ik heb een formulier met een listbox en ik wil met item uit de listbox een insert in de database maken.
Maar wanneer mijn Listbox bijvoorbeeld 3 personen bevat wordt de laatste dubbel geplaatst. Dat geld ook als het er 4,5,6 en zelfs 1 zijn.
Eerst heb ik een paar formulier checks en dan kom ik hier:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
// Voorkom SQL Injection
$PostClannaam = mysqli_real_escape_string($conn, $_POST['clannaam']);
$PostLand = mysqli_real_escape_string($conn, $_POST['land']);
// Maak war aan in database
$SQLInsertWar = "INSERT INTO war (naam, land, datum)
VALUES ('" . $PostClannaam . "', '" . $PostLand . "', '" . $newdate . "')";
// Controleer of insert is gelukt
if ($conn->query($SQLInsertWar) === FALSE) {
echo "<div class='error'>MySQL Error!! GVD @#$!!!</div>";
} else {
// Plaats warid in variable
$warid = $conn->insert_id;
// Haal alle gekozen warleden op van formulier
$list2 = $_POST['list2'];
foreach($list2 as $gebruikersnaam)
{
// Plaats warleden in database
$SQLInsertWarLeden = "INSERT INTO warstats (warid, gebruikersnaam)
VALUES ('" . $warid . "', '" . $gebruikersnaam . "')";
$conn->query($SQLInsertWarLeden);
}
// Controleer of insert is gelukt
if ($conn->query($SQLInsertWarLeden) === FALSE) {
echo "<div class='error'>MySQL Error 2!! GVD @#$!!!</div>";
} else {
// Haal de aangemaakte warleden op
$SQLSelectLeden = "SELECT warid, gebruikersnaam
FROM warstats
WHERE warid = '" . $warid . "'";
$ResultWarLeden = $conn->query($SQLSelectLeden);
// Laat de aangemaakte warleden zien
while($row = $ResultWarLeden->fetch_assoc()) {
echo "gebruikersnaam: " . $row["gebruikersnaam"]. "<br>";
}
}
}
?>
// Voorkom SQL Injection
$PostClannaam = mysqli_real_escape_string($conn, $_POST['clannaam']);
$PostLand = mysqli_real_escape_string($conn, $_POST['land']);
// Maak war aan in database
$SQLInsertWar = "INSERT INTO war (naam, land, datum)
VALUES ('" . $PostClannaam . "', '" . $PostLand . "', '" . $newdate . "')";
// Controleer of insert is gelukt
if ($conn->query($SQLInsertWar) === FALSE) {
echo "<div class='error'>MySQL Error!! GVD @#$!!!</div>";
} else {
// Plaats warid in variable
$warid = $conn->insert_id;
// Haal alle gekozen warleden op van formulier
$list2 = $_POST['list2'];
foreach($list2 as $gebruikersnaam)
{
// Plaats warleden in database
$SQLInsertWarLeden = "INSERT INTO warstats (warid, gebruikersnaam)
VALUES ('" . $warid . "', '" . $gebruikersnaam . "')";
$conn->query($SQLInsertWarLeden);
}
// Controleer of insert is gelukt
if ($conn->query($SQLInsertWarLeden) === FALSE) {
echo "<div class='error'>MySQL Error 2!! GVD @#$!!!</div>";
} else {
// Haal de aangemaakte warleden op
$SQLSelectLeden = "SELECT warid, gebruikersnaam
FROM warstats
WHERE warid = '" . $warid . "'";
$ResultWarLeden = $conn->query($SQLSelectLeden);
// Laat de aangemaakte warleden zien
while($row = $ResultWarLeden->fetch_assoc()) {
echo "gebruikersnaam: " . $row["gebruikersnaam"]. "<br>";
}
}
}
?>
Je voert de query op regel 33 nogmaals uit. Zet de controle rond regel 28 ipv de query te herhalen.
Bedankt Ben maar wanneer ik dat doe dan komt de errror er zo vaak te staan als er items zijn.
Dat klopt, dus zul je even moeten herstructureren. Als voorbeeld kun je uit de foreach springen als je een fout hebt (zie break).
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
// Voorkom SQL Injection
$PostClannaam = mysqli_real_escape_string($conn, $_POST['clannaam']);
$PostLand = mysqli_real_escape_string($conn, $_POST['land']);
// Maak war aan in database
$SQLInsertWar = "INSERT INTO war (naam, land, datum)
VALUES ('" . $PostClannaam . "', '" . $PostLand . "', '" . $newdate . "')";
// Controleer of insert is gelukt
if ($conn->query($SQLInsertWar) === FALSE)
{
echo "<div class='error'>MySQL Error!! GVD @#$!!!</div>";
}
else
{
// Plaats warid in variable
$warid = $conn->insert_id;
// Haal alle gekozen warleden op van formulier
$list2 = $_POST['list2'];
foreach($list2 as $gebruikersnaam)
{
// Plaats warleden in database
$SQLInsertWarLeden = "INSERT INTO warstats (warid, gebruikersnaam)
VALUES ('" . $warid . "', '" . $gebruikersnaam . "')";
$conn->query($SQLInsertWarLeden);
}
// Haal de aangemaakte warleden op
$SQLSelectLeden = "SELECT warid, gebruikersnaam
FROM warstats
WHERE warid = '" . $warid . "'";
// Controleer of insert is gelukt
if ($conn->query($SQLSelectLeden) === FALSE)
{
echo "<div class='error'>MySQL Error!! GVD @#$!!!</div>";
}
else
{
$ResultWarLeden = $conn->query($SQLSelectLeden);
// Laat de aangemaakte warleden zien
while($row = $ResultWarLeden->fetch_assoc()) {
echo "gebruikersnaam: " . $row["gebruikersnaam"]. "<br>";
}
}
}
?>
// Voorkom SQL Injection
$PostClannaam = mysqli_real_escape_string($conn, $_POST['clannaam']);
$PostLand = mysqli_real_escape_string($conn, $_POST['land']);
// Maak war aan in database
$SQLInsertWar = "INSERT INTO war (naam, land, datum)
VALUES ('" . $PostClannaam . "', '" . $PostLand . "', '" . $newdate . "')";
// Controleer of insert is gelukt
if ($conn->query($SQLInsertWar) === FALSE)
{
echo "<div class='error'>MySQL Error!! GVD @#$!!!</div>";
}
else
{
// Plaats warid in variable
$warid = $conn->insert_id;
// Haal alle gekozen warleden op van formulier
$list2 = $_POST['list2'];
foreach($list2 as $gebruikersnaam)
{
// Plaats warleden in database
$SQLInsertWarLeden = "INSERT INTO warstats (warid, gebruikersnaam)
VALUES ('" . $warid . "', '" . $gebruikersnaam . "')";
$conn->query($SQLInsertWarLeden);
}
// Haal de aangemaakte warleden op
$SQLSelectLeden = "SELECT warid, gebruikersnaam
FROM warstats
WHERE warid = '" . $warid . "'";
// Controleer of insert is gelukt
if ($conn->query($SQLSelectLeden) === FALSE)
{
echo "<div class='error'>MySQL Error!! GVD @#$!!!</div>";
}
else
{
$ResultWarLeden = $conn->query($SQLSelectLeden);
// Laat de aangemaakte warleden zien
while($row = $ResultWarLeden->fetch_assoc()) {
echo "gebruikersnaam: " . $row["gebruikersnaam"]. "<br>";
}
}
}
?>
Hier worden ook queries dubbel uitgevoerd. Daarnaast verander je gewoon het gedrag van het script, wat me niet de bedoeling lijkt te zijn,
Ook is het misschien handig om een wrapper class voor je database te schrijven zodat een query een exception throwt als er iets misgaat. Dan kun je in plaats van die if-elseif-else-hel alles gewoon in een try-catch blok zetten.
Oh, en voor de goede orde zou het geheel misschien in een transactie gezet moeten worden zodat alle (INSERT) queries in zijn geheel, of in zijn geheel niet worden doorgevoerd. Als dit script ergens halverwege de mist in gaat heb je nu mogelijk troep in je database.
op regel 27 is gebruikersid niet ge-escaped
Ivo P op 30/09/2015 17:01:32:
en escape ALLE gebruikersinvoer.
op regel 27 is gebruikersid niet ge-escaped
op regel 27 is gebruikersid niet ge-escaped
Ofwel dat, ofwel filter de invoer (controleer of de gebruikersnamen geldig zijn - en om dat te doen heb je weer een query nodig waarin de boel ge-escaped moet worden waarschijnlijk, see how that works :)).
En je kunt dus beter id's gebruiken.
Gewijzigd op 30/09/2015 17:15:34 door Thomas van den Heuvel
Ik zal gebruikers input gaan "escapen" en het klopt wat Thomas zegt dat wanneer dit script halverwege wordt onderbroken ik al zooi in me database heb en dat wil ik inderdaad niet.
Ik ga eens op zoek naar een "transactie" ?!
Maar volgens mij heb ik nog geen oplossing gehoord om die dubbele insert te voorkomen?
EDIT: Gebruikersnaam komt uit een lijst wat een user niet zelf invult dus escapen is denk ik niet nodig??
En ik heb nu een check in het script toegevoegd of de war niet al bestaat. Dus wanneer de pagina wordt ververst komt er geen dubbele insert en ga je met een goto naar het tweede gedeelte van het script.
Gewijzigd op 01/10/2015 17:05:53 door Danny von Gaal
Quote:
Maar volgens mij heb ik nog geen oplossing gehoord om die dubbele insert te voorkomen?
Ben van Velzen noemde de oorzaak al: je voert op regel 33 nogmaals de query uit van de laatste iteratie van de foreach-lus van regel 22-30.
In het zelfde antwoord geeft hij tevens aan hoe je dit op moet lossen.
Als dat fouten oplevert zoals je zelf aangeeft, zul je moeten kijken waar die dan vandaan komen. Druk de query die fouten oplevert eens af, wordt er een UNIQUE constraint geschonden ofzo?
Thomas van den Heuvel op 01/10/2015 17:24:00:
Ben van Velzen noemde de oorzaak al: je voert op regel 33 nogmaals de query uit van de laatste iteratie van de foreach-lus van regel 22-30.
In het zelfde antwoord geeft hij tevens aan hoe je dit op moet lossen.
Quote:
Maar volgens mij heb ik nog geen oplossing gehoord om die dubbele insert te voorkomen?
Ben van Velzen noemde de oorzaak al: je voert op regel 33 nogmaals de query uit van de laatste iteratie van de foreach-lus van regel 22-30.
In het zelfde antwoord geeft hij tevens aan hoe je dit op moet lossen.
Ohja, daar heb ik denk ik overheen gelezen.
Via een break;
Het is gelukt!
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
// Haal alle gekozen warleden op van formulier
$list2 = $_POST['list2'];
foreach($list2 as $gebruikersnaam)
{
// Plaats warleden in database
$SQLInsertWarLeden = "INSERT INTO warstats (warid, gebruikersnaam)
VALUES ('" . $_SESSION['warid'] . "', '" . $gebruikersnaam . "')";
if ($conn->query($SQLInsertWarLeden) === FALSE) {
echo "<div class='error'>MySQL Error 2!! GVD @#$!!!</div>";
break;
}
}
?>
// Haal alle gekozen warleden op van formulier
$list2 = $_POST['list2'];
foreach($list2 as $gebruikersnaam)
{
// Plaats warleden in database
$SQLInsertWarLeden = "INSERT INTO warstats (warid, gebruikersnaam)
VALUES ('" . $_SESSION['warid'] . "', '" . $gebruikersnaam . "')";
if ($conn->query($SQLInsertWarLeden) === FALSE) {
echo "<div class='error'>MySQL Error 2!! GVD @#$!!!</div>";
break;
}
}
?>
Gewijzigd op 01/10/2015 18:10:34 door Danny von Gaal