Door
Donovan -
op 10-03-2019 15:28
gewijzigd op 10-03-2019 15:43
3.530 views
Hoi!
Ik wil een tabel updaten met informatie. De SQL-Query werkt prima, data word geüpdatete, toch blijft er een waarschuwing verschijnen dat er iets niet goed is in de Query.
$token = $_GET['token']; // vanuit de browser-url
$sql_update = $db_handle->runQuery("UPDATE gebruikers SET Geactiveerd = 'Ja' WHERE Token = '$token' ");
// daar komt uit bijvoorbeeld (geëchood) SQL = UPDATE gebruikers SET Geactiveerd = 'Ja' WHERE Token = '89230c74d68fb7f2ba88'
//Foutmelding: Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given in C:\xampp\htdocs\NCD\dbcontroller.php on line 25
// DB Controller functie
function runQuery($query) {
$result = mysqli_query($this->conn,$query);
while($row = mysqli_fetch_assoc($result))
{
$resultset[] = $row;
}
if(!empty($resultset))
return $resultset;
}
Dus het werkt, wel, alleen de waarschuwing blijft. Ik gebruik eerder een andere SELECT-query en die werkt prima;
$sql_check = $db_handle->numRows("SELECT * FROM gebruikers WHERE Token = '$token' ");
Iemand enig idee hoe dit kan? Het lijkt dus of een SELECT Query prima werkt, alleen bij een UPDATE werkt het niet..
PHP(.net) heeft uitstekende documentatie. Zo staat bij elke functie/methode beschreven wat deze teruggeven in verschillende gevallen (onder het kopje Return Values).
Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or EXPLAIN queries mysqli_query() will return a mysqli_result object. For other successful queries mysqli_query() will return TRUE.
Trouwens het uitvoeren van een query en ophalen van resultaten zijn twee compleet verschillende dingen, waarom zou je die bij elkaar gooien in runQuery?
Wat Thomas zegt, zeker even die token valideren alvorens iets met de database te doen.
Ik gebruik altijd gewoon een database class en daar kan je eenvoudig dan zo met de database communiceren:
<?php
$database = new database();
$q = "query";
$result = $database->query($q);
while ($row = mysqli_fetch_assoc($result)
{
echo $row['kolom naam die je wilt'];
}
en die injectie een nieuwe functie gemaakt. Is't wat?
function quote($value) {
return mysqli_real_escape_string($this->conn, $value);
}
Nee, want die functie doet niet wat 'ie zegt dat 'ie doet. Deze heet "quote". De functie voegt nergens quotes toe. Een betere "shorthand" zou "escape" kunnen zijn.
Het escapen van DATA-delen in SQL is trouwens niet veilig zonder quotes, dus ook die zou je toe moeten voegen. Waar je dit doet... ik doe dit in de SQL zelf, maar als je dat in een functie of methode doet zou dit ergens in de naamgeving uit moeten blijken.
Ik zou bovenstaande functie niet gebruiken, en wel om de volgende redenen:
- deze past je invoer aan; mogelijk hebben spaties, regelovergangen et cetera betekenis; deze op voorhand strippen met trim() lijkt mij geen goed plan
- deze escaped invoer, dat is over het algemeen onverstandig, enkele uitzonderingen daargelaten; hierbij ga je er ook vanuit dat de data enkel (?) in een HTML-context gebruikt wordt, dit hoeft niet op voorhand vast te staan; ook wil je mogelijk rauwe HTML kunnen gebruiken en dan zou je dus de omgekeerde bewerking moeten uitvoeren; dit is allemaal niet optimaal
- deze escaped voor meerdere contexten tegelijkertijd (zowel voor HTML en voor SQL), dit is ook niet echt handig
- de naamgeving (check_input) suggereert iets anders dan wat het doet, het past mogelijk inhoudelijk $data aan; dit laatste is wat mij betreft ook onwenselijk: het is in bijna alle gevallen een beter plan om alle data "rauw" op te slaan, ongewijzigd, zoals je het aangeleverd krijgt
Dit is voor mijn doeleinde meestal genoeg om te zorgen dat er geen sql injectie mogelijk is.
Ook dat klopt niet helemaal want het gebruik van enkel real_escape_string() is niet genoeg (interne link).
In het algemeen is het verstandiger om escaping in een bepaalde context (HTML, SQL et cetera) altijd uit te stellen tot net voor het gebruik van data in de betreffende context.
Tuurlijk Thomas, er is geen enkele functie die voor elke situatie de data kan escapen maar voor 90% van mijn velden (formuliertjes) simpele text fields is dit prima. Uiteraard check ik bij de post ook op andere zaken alvorens de data naar de database te sturen maar als basis neem ik de check_input functie en vanaf daar run ik meerdere functies erop. (strlen, strtolower, regex etc).