Delete functie werkt niet

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Max Amelsfort

Max Amelsfort

06/11/2018 14:52:13
Quote Anchor link
Goedemiddag,

Ik ben bezig met een delete functie waarbij ik uit 3 tabellen gegevens wil wissen. Eerst heb ik het ID van de bepaalde speler opgezocht in mijn database en daarna wil ik alle gegevens met die ID verwijderen. Dit is mijn code maar het werkt niet, kan iemand mij helpen?

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
require('connection.php');
$player = $_POST['player_name'];
$query = "SELECT player_id FROM player WHERE player_name = '$player';";
$resultaat = mysqli_query($connectie, $query);
$rij = mysqli_fetch_array($resultaat);
$queryverwijderplayer = "DELETE FROM player WHERE player_id = $rij['player_id'];";
echo $queryverwijderplayer;
?>
 
PHP hulp

PHP hulp

26/11/2024 12:29:07
 
Bart V B

Bart V B

06/11/2018 14:59:22
Quote Anchor link
Afgezien dat je eerst moet kijken of er gepost word, en dat dit lek is, zou het zo moeten werken volgens mij.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
require('connection.php');
$player = $_POST['player_name'];
$query = "SELECT player_id FROM player WHERE player_name = '".$player."'";
$resultaat = mysqli_query($connectie, $query);
$rij = mysqli_fetch_array($resultaat);
$queryverwijderplayer = "DELETE FROM player WHERE player_id = '".$rij['player_id']."'";
echo $queryverwijderplayer;
?>
Gewijzigd op 06/11/2018 14:59:48 door Bart V B
 
Max Amelsfort

Max Amelsfort

06/11/2018 15:02:43
Quote Anchor link
Dankjewel!
 
- Ariën  -
Beheerder

- Ariën -

06/11/2018 15:44:46
Quote Anchor link
Het kan geen kwaad om wat foutafhandeling toe te voegen met mysqli_error($connectie).

Zorg er ook voor dat je mysqli_real_escape_string() gebruikt.
 
Thomas van den Heuvel

Thomas van den Heuvel

06/11/2018 16:42:28
Quote Anchor link
Aan de bovenstaande code rammelt nog van alles:
- input wordt niet gefilterd/gevalideerd, ook zou het beter zijn om direct met een id te werken (zie toelichting verderop)
- output zou ge-escaped moeten worden zoals @Ariën aanhaalt, op dit moment is SQL-injectie mogelijk; misschien is het met wat kunst- en vliegwerk zelfs mogelijk om alle of willekeurige spelers op deze manier te verwijderen
- dit zou voor de goede orde misschien in een transactie moeten staan
- je controleert niet eens of de eerste query een resultaat oplevert maar je gaat er blindelings vanuit dat die query een resultaat heeft

Het enige wat effectief is veranderd is de verwijdering van punt-komma's in de queries en het toevoegen van quotes om het player id?

Maar los daarvan, de hele opzet is logisch gezien... niet erg logisch. Ik bedoel, als je dan toch een selectie doet op spelersnaam, en vervolgens die speler dan op grond van het bijbehorende id verwijdert, waarom verwijder je dan niet meteen een speler op basis van spelersnaam? Of dus beter, door alleen te werken met speler ids, zodat er nooit een naam aan te pas komt, wat de kans op het verwijderen van een verkeerde speler verder wegneemt.

En dan het verwijderen zelf, misschien is dat ook geen goed idee. Voor wanneer er toch per ongeluk de verkeerde speler wordt verwijderd. Zou het niet beter zijn om een status "deleted" bij te houden, zodat "verwijderde" spelers eventueel ook weer teruggehaald kunnen worden?
 
Bart V B

Bart V B

06/11/2018 19:15:34
Quote Anchor link
Quote:
Het enige wat effectief is veranderd is de verwijdering van punt-komma's in de queries en het toevoegen van quotes om het player id?

Volgens mij vroeg Max toch echt waarom het niet werkte.
Om de code te laten werken was dat nodig. Dus, what is your point?

Ik geef er nog bij aan dat hij eigenlijk eerst een controle moet doen om te kijken of er überhaupt is gepost, en ook nog dat het lek is. Ja, het kan allemaal beter. Is het goed om advies te geven? Zeker.
Maar je ziet toch ook wel dat Max daar nog niet zover in is....
 
Thomas van den Heuvel

Thomas van den Heuvel

06/11/2018 21:15:15
Quote Anchor link
Bart V B op 06/11/2018 19:15:34:
Volgens mij vroeg Max toch echt waarom het niet werkte.
Om de code te laten werken was dat nodig. Dus, what is your point?

Nou, je gaf alleen een nieuw codefragment zonder enige toelichting. Wat kan de topicstarter daar van leren? Dit is toch geen "zoek de 10 verschillen" website?

Bart V B op 06/11/2018 19:15:34:
Ik geef er nog bij aan dat hij eigenlijk eerst een controle moet doen om te kijken of er überhaupt is gepost, en ook nog dat het lek is. Ja, het kan allemaal beter. Is het goed om advies te geven? Zeker.
Maar je ziet toch ook wel dat Max daar nog niet zover in is....

Reden te meer om te onderbouwen wat je doet, en nog belangrijker, waarom. En ook om op een gegeven moment een waardeoordeel te geven over de code waar je mee bezig bent. In dit geval lijkt het mij ofwel verstandiger om opnieuw te beginnen, of dit maar te laten rusten. Als dit slechts een fragment is van een veel grotere applicatie, grote kans dat daar ook enorme gaten in zitten, wat heeft het dan voor zin om dit stukje op te lappen?
Gewijzigd op 06/11/2018 21:16:15 door Thomas van den Heuvel
 
Max Amelsfort

Max Amelsfort

07/11/2018 07:41:55
Quote Anchor link
Dankjewel voor de reacties, ik ben inderdaad nog een beginner in PHP. De my_sqli error zit er al in bij connection.php dus die heb ik dan niet nodig neem ik aan. Ik heb nu gezorgd dat de value van de vorige pagina het ID van de speler is in plaats van de naam, daarmee heb ik dit gekregen

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
require('connection.php');
$player = mysqli_real_escape_string( $connectie, $_POST['player_name']);
$queryverwijderplayer = "DELETE FROM player WHERE player_id = $player;";
$queryverwijderclub = "DELETE FROM club WHERE player_id = $player;";
$queryverwijdertime = "DELETE FROM time WHERE player_id = $player;";
$resultaatplayer = mysqli_query($connectie, $queryverwijderplayer);
$resultaatclub = mysqli_query($connectie, $queryverwijderclub);
$resultaattime = mysqli_query($connectie, $queryverwijdertime);
header('Location: beveiligdepagina.php');
exit();
?>
 
- Ariën  -
Beheerder

- Ariën -

07/11/2018 08:45:15
Quote Anchor link
Foutafhandeling hoort eigenlijk op elke query en connectie.Elk van die kan fout gaan.
 
Max Amelsfort

Max Amelsfort

07/11/2018 08:59:30
Quote Anchor link
- Ariën - op 07/11/2018 08:45:15:
Foutafhandeling hoort eigenlijk op elke query en connectie.Elk van die kan fout gaan.


Dus je bedoelt dat ik bij elke query erbij moet zetten:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
if ($resultaat == false){
echo 'Something went wrong, try again!';
die;
}

?>
 
- Ariën  -
Beheerder

- Ariën -

07/11/2018 09:08:31
Quote Anchor link
Ja, maar gebruik van die() is niet netjes.
Wij sterven toch ook niet als we wat fout doen? ;-)

Ikzelf gebruik de Object-georienteerde versie van MySQLi (met pijltjes, waaronder: $db->query(.....) ). In een MySQL extended class overschrijf ik de query() functie en voeg daar standaard foutafhandeling toe (als Exception).

Vanaf dan heb ik bij elke query een foutafhandeling zonder dat ik ze hoef te verpakken met if-statements.
Gewijzigd op 07/11/2018 09:11:33 door - Ariën -
 
Thomas van den Heuvel

Thomas van den Heuvel

07/11/2018 15:48:35
Quote Anchor link
Max Amelsfort op 07/11/2018 07:41:55:
Ik heb nu gezorgd dat de value van de vorige pagina het ID van de speler is in plaats van de naam, daarmee heb ik dit gekregen.

Okay, maar waarom heeft dat id nog de naam player_name? Dat is op zijn zachtst gezegd misleidend. Geef alles zelf-uitleggende namen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
require('connection.php');
$player = mysqli_real_escape_string( $connectie, $_POST['player_name']);
$queryverwijderplayer = "DELETE FROM player WHERE player_id = $player;";
$queryverwijderclub = "DELETE FROM club WHERE player_id = $player;";
$queryverwijdertime = "DELETE FROM time WHERE player_id = $player;";
$resultaatplayer = mysqli_query($connectie, $queryverwijderplayer);
$resultaatclub = mysqli_query($connectie, $queryverwijderclub);
$resultaattime = mysqli_query($connectie, $queryverwijdertime);
header('Location: beveiligdepagina.php');
exit();
?>

Uh oh. Je gebruikt hier weliswaar real_escape_string(), maar dit is niet veilig zonder dit te combineren met quotes.

real_escape_string() is géén wondermiddel. Als er niets te escapen valt, wordt er ook niets ge-escaped. Stel dat je user 6 wilt verwijderen, maar dit combineert met "OR 1=1". Voer je hier real_escape_string() op uit dan blijft dit "6 OR 1=1". Ik hoef je waarschijnlijk niet te vertellen wat er gebeurt als je deze query uitvoert:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
DELETE FROM player WHERE player_id = 6 OR 1=1

(spoiler: alle players worden verwijderd)
Het feit dat je daarna(ast) allerlei data uit losse tabellen moet verwijderen baart mij ook zorgen. Dit impliceert min of meer dat dit geen echte relationele database is, en alle tabellen als los zand aan elkaar hangen :/.
 
Max Amelsfort

Max Amelsfort

07/11/2018 16:15:59
Quote Anchor link
Thomas van den Heuvel op 07/11/2018 15:48:35:
Max Amelsfort op 07/11/2018 07:41:55:
Ik heb nu gezorgd dat de value van de vorige pagina het ID van de speler is in plaats van de naam, daarmee heb ik dit gekregen.

Okay, maar waarom heeft dat id nog de naam player_name? Dat is op zijn zachtst gezegd misleidend. Geef alles zelf-uitleggende namen.

Uh oh. Je gebruikt hier weliswaar real_escape_string(), maar dit is niet veilig zonder dit te combineren met quotes.


Hoe moeten de quotes er dan omheen?



Toevoeging op 07/11/2018 16:17:50:

- Ariën - op 07/11/2018 09:08:31:
Ja, maar gebruik van die() is niet netjes.
Wij sterven toch ook niet als we wat fout doen? ;-)

Ikzelf gebruik de Object-georienteerde versie van MySQLi (met pijltjes, waaronder: $db->query(.....) ). In een MySQL extended class overschrijf ik de query() functie en voeg daar standaard foutafhandeling toe (als Exception).

Vanaf dan heb ik bij elke query een foutafhandeling zonder dat ik ze hoef te verpakken met if-statements.


Ik heb "die" overal gebruikt omdat ik daarmee zorg dat de rest van de code ook niet wordt uitgevoerd als de verbinding of query niet goed is. Zo heb ik dat ook geleerd
 
- Ariën  -
Beheerder

- Ariën -

07/11/2018 16:30:43
Quote Anchor link
Zo doe je dat....

Dus de query wordt uiteindelijk bijv.
DELETE FROM player WHERE player_id = '8'

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$player
= mysqli_real_escape_string( $connectie, $_POST['player_name']);
$queryverwijderplayer = "DELETE FROM player WHERE player_id = '".$player."'";
?>


Zelf raad ik aan om de mysqli_real_escape_string() toe te voegen in de opdracht zelf. Dan heb je direct een goed overzicht of je niks vergeten bent. Het zou vervelend zijn als je toch ergens overheen leest, een rotte querie hebt die misbruik wordt, en dat eventuele persoonsgegevens op straat ligt.


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$queryverwijderplayer
= "DELETE FROM player
            WHERE player_id = '"
.mysqli_real_escape_string($connectie, $_POST['player_name'])."'";
?>


En over je die(). Die moet je nooit gebruiken. De functie die() laat je script direct stoppen, en dat is nooit de oplossing. Je layout wordt opeens afgebroken, en eventuele belangrijke script daarna worden ook niet meer geladen.

Ikzelf gebruik de object-georiënteerde versie van MySQLi, en pas de foutafhandeling zo toe:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class Database extends mysqli {
    
    var
$totalQueries = 0;
        
    function
query($query)
    {

        $result = parent::query($query);
        if($this->error) {
            throw new Exception(mysqli_error($this), mysqli_errno($this));
        }

        return $result;
    }
}
  
?>


Waarna ik dus De class initieer en de queries uitvoer met:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$db
= new Database(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$db->query("SELECT dit, dat, FROM dingen");
?>


Als er wat fout gaat in de query, dan krijg je mooi een exception voor de kiezen die je met de exception_handler kan aanpassen (of je werkt met try-catch blokken)
Gewijzigd op 07/11/2018 16:31:47 door - Ariën -
 
Max Amelsfort

Max Amelsfort

07/11/2018 16:33:56
Quote Anchor link
Super bedankt!
 
Thomas van den Heuvel

Thomas van den Heuvel

07/11/2018 16:38:42
Quote Anchor link
Een niet gevangen exception resulteert altijd in een fatal error. Op het moment dat je een weg inslaat met exceptions dan is het ook zaak dat je try-catch blokken om die functionaliteit zet... Of je implementeert dus die custom exception handler, maar het effect is dan hetzelfde als een die(), immers:
Quote:
Execution will stop after the exception_handler is called.

En een try-catch eigenlijk ook, immers:
Quote:
When an exception is thrown, code following the statement will not be executed, and PHP will attempt to find the first matching catch block.
Gewijzigd op 07/11/2018 16:46:08 door Thomas van den Heuvel
 
- Ariën  -
Beheerder

- Ariën -

07/11/2018 17:02:23
Quote Anchor link
Die exceptionhandler heb ik ooit eens gebouwd omdat ik die wildgroei aan try-catch blokken zat was in de losse scripts. Maar nu ik dit via een 'single-point of entry' afhandel, en dus alles via index.php laat binnensluizen zou die try-catch daar kunnen worden geplaatst. De afhandeling voor de exception gaat bij mij via een template die een templateparser verwerkt.

Maar goed, in mijn voorbeeld is de afhandeling sowieso centraal geregeld, zonder dat je je hele applicatie hoeft om te bouwen naar statements om je queries.
 
Thomas van den Heuvel

Thomas van den Heuvel

07/11/2018 17:07:25
Quote Anchor link
Precies, op het moment dat je jezelf de try-catch architectuur aanmeet is dat van invloed, of liever gezegd, dit wordt allesbepalend, op de algehele structuur van je applicatie.

Dit kun je met geen fatsoen in gaan bouwen in een verzameling van scripts die deze aanpak niet volgt, tenzij je dus de hele opbouw hier op afstemt, in welk geval je gewoon beter opnieuw kunt beginnen.

En al helemaal als het fundament (de database) nogal krakkemikkig is.
 
Ward van der Put
Moderator

Ward van der Put

07/11/2018 18:12:51
Quote Anchor link
Misschien dan toch bij die database beginnen, want je kunt dit beperken tot één DELETE als je de relaties goed instelt:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$queryverwijderplayer
= "DELETE FROM player WHERE player_id = $player;";
$queryverwijderclub = "DELETE FROM club WHERE player_id = $player;";
$queryverwijdertime = "DELETE FROM time WHERE player_id = $player;";
?>
 
- Ariën  -
Beheerder

- Ariën -

07/11/2018 18:38:30
Quote Anchor link
Maar is deleten echt nodig? Hiermee verdwijnen mogelijk al je koppelingen, mocht je die hebben gemaakt.
Ikzelf raad aan om alles te flaggen als verwijderd. Zo voorkom je ook een 'f*ck up' als je per ongeluk het verkeerde verwijdert.
 
Thomas van den Heuvel

Thomas van den Heuvel

07/11/2018 19:04:12
Quote Anchor link
- Ariën - op 07/11/2018 18:38:30:
Ikzelf raad aan om alles te flaggen als verwijderd. Zo voorkom je ook een 'f*ck up' als je per ongeluk het verkeerde verwijdert.

Inderdaad, dat had ik hierboven ook al aangehaald.
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.