Kan iemand mij het misschien uitleggen? Want ik snap het echt niet.
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:
<?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>";
}
}
}
?>
Ik zie ook overal namen staan, zouden dat geen id's moeten zijn? Verder lijkt mij een war iets tussen twee clan(-id)s?
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.
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 :)).
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.
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?