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).

Om de documentatie maar weer te quoten:
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?
Bij een UPDATE retourneert mysqli_query true indien alles OK. Daar kun je dus geen rijen uit trekken.


function runQuery($query) {
    $result = mysqli_query($this->conn,$query);
    if(!$result) return false; //of throw een error
    if($result === true) return true; //alles OK, maar geen resultset
    while($row = mysqli_fetch_assoc($result)) 
    {
        $resultset[] = $row;
    }        
    if(!empty($resultset))
        return $resultset;
}


Zoek in Google overigens ook eens naar "SQL injectie" mbt je gebruik van $token direct in de query.

[size=xsmall]Toevoeging op 10/03/2019 17:21:58:[/size]

Damn, 6 seconden te laat ;-)
En ja, om het maar niet te hebben over SQL-injectie ;).
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'];
}



?>
Dat is ook wat ik gebruik. Ik zelf gebruik een extended classe met MySQLi waarbij ik de foutafhandeling in de query() functie geïntegreerd heb.
Rob Doemaarwat op 10/03/2019 17:21:13

Bij een UPDATE retourneert mysqli_query true indien alles OK. Daar kun je dus geen rijen uit trekken.


function runQuery($query) {
    $result = mysqli_query($this->conn,$query);
    if(!$result) return false; //of throw een error
    if($result === true) return true; //alles OK, maar geen resultset
    while($row = mysqli_fetch_assoc($result)) 
    {
        $resultset[] = $row;
    }        
    if(!empty($resultset))
        return $resultset;
}


Zoek in Google overigens ook eens naar "SQL injectie" mbt je gebruik van $token direct in de query.

[size=xsmall]Toevoeging op 10/03/2019 17:21:58:[/size]

Damn, 6 seconden te laat ;-)


Heb in ieder geval hier een nieuwe updateQuery functie van gemaakt.
en die injectie een nieuwe functie gemaakt. Is't wat?


function quote($value) { 
	return mysqli_real_escape_string($this->conn, $value); 
}
Donovan - op 15/03/2019 20:10:44
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 raad aan om een functie te schrijven die je kan gebruiken om user input te escapen:

function check_input($data)
{

$database = new database();
$data = trim(htmlentities($data));

return mysqli_real_escape_string($database->getConnection(),$data);
}

Dit is voor mijn doeleinde meestal genoeg om te zorgen dat er geen sql injectie mogelijk is.
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).

Reageren