Rare errormelding 'near, bij variabele toevoegen
Ja, weer een vraag. Ik heb een select ui de database gemaakt bij in form. Als ik uit de select :Energiebesparende Scenario's Maatwerk (G-A+++) kies, en vervolgens naar de mysql wegschrijf krijg ik de errormelding dat near in line 1 niet goed is. Bij alle andere keuzes gaat het goed. Alleen bij "Energiebesparende Scenario's Maatwerk (G-A+++)" niet. Als ik G-A+++ verander dan wel. Wat is hiervan de oorzaak. Ik hoef deze invoer niet te sanitizen omdat het uit de database zelf komt en via select weer terug gaat in een andere tabel in een veld omschrijving VARCHAR. Helpen jullie mij WEER op weg? Dank
Enerzijds heb je quotes nodig om waarden voor tekstkolommen af te bakenen, anderzijds kan deze data zelf quotes bevatten waardoor deze twee door elkaar gaan lopen.
Hier zijn specifiek de real_escape_string() functies en methoden voor bedoeld zodat DATA niet als SQL wordt geïnterpreteerd, wat ook handig kan zijn om SQL-injectie tegen te gaan.
Dat gezegd hebbende, dump de query eens naar je scherm, dan kun je zien welke concrete query misgaat.
Gewijzigd op 30/03/2018 22:58:16 door Thomas van den Heuvel
Jan te Pas op 30/03/2018 22:34:32:
Ik hoef deze invoer niet te sanitizen omdat het uit de database zelf komt en via select weer terug gaat in een andere tabel in een veld omschrijving VARCHAR.
Toch maar wel doen. Het is heel eenvoudig om in de browser de waarden van de select aan te passen (en dus SQL te injecteren).
Dat ga ik doen. Mijn query was eenvoudig de velden in te lezen en te plaatsen. Zie hier de code, na openen:
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
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
<?php
$sql = "SELECT * FROM `product`";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data, vul select
echo '<label>KIES HIER HET PRODUCT</font></label>';
echo '<select name="productsoort" id="productsoort" title="(Kies hier het gewenste product)">';
//1e select ook als selected markeren
$selecteer=true;
while($row = $result->fetch_assoc()) {
echo '<option value="';
echo $row["product"];
if ($selecteer) {
echo '" selected >';
$selecteer=false;
// eerste regel selecteren en nu niet meer
} else {
echo '">';
}
echo $row["product"];
echo '</option>';
}
echo '</select>';
} else {
echo "Nog geen producten aanwezig";
}
?>
$sql = "SELECT * FROM `product`";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data, vul select
echo '<label>KIES HIER HET PRODUCT</font></label>';
echo '<select name="productsoort" id="productsoort" title="(Kies hier het gewenste product)">';
//1e select ook als selected markeren
$selecteer=true;
while($row = $result->fetch_assoc()) {
echo '<option value="';
echo $row["product"];
if ($selecteer) {
echo '" selected >';
$selecteer=false;
// eerste regel selecteren en nu niet meer
} else {
echo '">';
}
echo $row["product"];
echo '</option>';
}
echo '</select>';
} else {
echo "Nog geen producten aanwezig";
}
?>
En hier de code voor het wegschrijven:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
// Maak connectie
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connectie
if ($conn->connect_error) {
die("Connectie mislukt: " . $conn->connect_error);
}
$sql = "INSERT INTO projecten(user, productsoort, omschrijving) VALUES ($id, '$product', '$omschrijving')";
//check of gelukt
if ($conn->query($sql) === TRUE) {
$nummer = mysqli_insert_id ( $conn);
} else {
echo "Fout: " . $sql . "<br>" . $conn->error;
}
$conn->close();
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connectie
if ($conn->connect_error) {
die("Connectie mislukt: " . $conn->connect_error);
}
$sql = "INSERT INTO projecten(user, productsoort, omschrijving) VALUES ($id, '$product', '$omschrijving')";
//check of gelukt
if ($conn->query($sql) === TRUE) {
$nummer = mysqli_insert_id ( $conn);
} else {
echo "Fout: " . $sql . "<br>" . $conn->error;
}
$conn->close();
Inderdaad, nergens escapen. Ik zal eea moeten aanpassen met real_escape_string(). Hebben julle nog suggesties? Dank!
Toevoeging op 31/03/2018 09:56:56:
Alles omgezet volgens jullie aanbevelingen. Fout nu opgelost. Dank. Weer wat geleerd. En sterker nog, een belangrijk deel ivm sql-injecties. Dank voor het delen van jullie kennis. Ik word er beter van in mijn aanpak. Vette pluim!
Gewijzigd op 31/03/2018 09:25:50 door Jan te Pas
Dus zorg ervoor dat je altijd je invoer van je data in je query netjes escaped, of voorziet van 'parametered queries'. Zo loop je nooit tegen het feit aan dat je query niet uitvoert als je bijvoorbeeld 's Gravenshave invoert. En ga ook nooit functies bouwen om dergelijke MyQL-functies en keywords als DROP en DELETE te blokkeren om hacking tegen te gaan.
In een ver verleden had iemand een stationsdatabase gemaakt met een dergelijke beveiliging, en bij station Purmerend Overwhere ging dat script dus onderuit. ;-)
Als ik een andere tip mag geven: Gebruik liever geen procedureel en object-georienteerd door elkaar. Het kan wel, en de performance zal niet veel anders zijn, maar in sommige gevallen is er verschil in het object die je gebruikt, wat tot bugs kan leiden. Kies dus één type en ga daar mee verder.
Gewijzigd op 31/03/2018 11:06:24 door - Ariën -
character encoding heeft.
Zo ook een HTML-document (de output van een PHP-script), maar ook de database, een tabel, een kolom en de data daarin hebben alle (default) character encoderingen. Ook bij de communicatie TUSSEN de database en je PHP-code maak je (waarschijnlijk tot nu toe onbewust) afspraken over de character encoding waarin je communiceert.
Hier MOET je je van bewust zijn en hier MOET je op acteren, anders kom je op den duur hopeloos in de problemen.
Zo zou je:
- een header() tag in je code moeten zetten, of een <meta> tag in de head van je HTML-document die aangeeft van welke character encoding alle content/output is
- een character encoding moeten selecteren bij het maken van je database, om op die manier expliciet vast te leggen hoe je communiceert
- na moeten gaan dat dit alles ook in lijn is met je tabeldefinities en -data (mogelijk is eerder ingevoegde data van een andere character encoding, als je dan de character encoding aanpast (in wezen verbetert) dan krijg je (potentieel) problemen met eerder ingevoerde data)
- er zorg voor moeten dragen dat dit alles (code en statische HTML, connectie met database, database-, tabel- en/of kolomdefinities en last but not least de data in deze tabellen zelf) in één lijn loopt, oftewel dat alles van dezelfde character encoding is zodat er geen vertalingen hoeven plaats te vinden maar nog veel belangrijker: dat er geen vertaalFOUTEN kunnen plaatsvinden
Dit alles is vervolgens weer belangrijk omdat escaping-functionaliteit van toepassing is op een specifieke character encoding. Het is dus zaak dat alle data dus ook van een voorgeschreven character encoding is anders is niet gegarandeerd dat de escaping-functionaliteit (die altijd van toepassing is op een specifieke character encoding) correct werkt.
EDIT: voer voor de gein eens een SHOW CREATE TABLE <willekeurige tabel>; uit, grote kans dat daar dan latin1 als charset staat, terwijl je alles behandeld als UTF-8, terwijl je dat gemakshalve vergeten bent bij het maken van de connectie.
Ik snap dat dit de boel ingewikkelder maakt, maar er komt een hoop tegelijkertijd samen als je met een database gaat werken. Daarom toch het volgende. Allereerst de realisatie dat alle tekst een Zo ook een HTML-document (de output van een PHP-script), maar ook de database, een tabel, een kolom en de data daarin hebben alle (default) character encoderingen. Ook bij de communicatie TUSSEN de database en je PHP-code maak je (waarschijnlijk tot nu toe onbewust) afspraken over de character encoding waarin je communiceert.
Hier MOET je je van bewust zijn en hier MOET je op acteren, anders kom je op den duur hopeloos in de problemen.
Zo zou je:
- een header() tag in je code moeten zetten, of een <meta> tag in de head van je HTML-document die aangeeft van welke character encoding alle content/output is
- een character encoding moeten selecteren bij het maken van je database, om op die manier expliciet vast te leggen hoe je communiceert
- na moeten gaan dat dit alles ook in lijn is met je tabeldefinities en -data (mogelijk is eerder ingevoegde data van een andere character encoding, als je dan de character encoding aanpast (in wezen verbetert) dan krijg je (potentieel) problemen met eerder ingevoerde data)
- er zorg voor moeten dragen dat dit alles (code en statische HTML, connectie met database, database-, tabel- en/of kolomdefinities en last but not least de data in deze tabellen zelf) in één lijn loopt, oftewel dat alles van dezelfde character encoding is zodat er geen vertalingen hoeven plaats te vinden maar nog veel belangrijker: dat er geen vertaalFOUTEN kunnen plaatsvinden
Dit alles is vervolgens weer belangrijk omdat escaping-functionaliteit van toepassing is op een specifieke character encoding. Het is dus zaak dat alle data dus ook van een voorgeschreven character encoding is anders is niet gegarandeerd dat de escaping-functionaliteit (die altijd van toepassing is op een specifieke character encoding) correct werkt.
EDIT: voer voor de gein eens een SHOW CREATE TABLE <willekeurige tabel>; uit, grote kans dat daar dan latin1 als charset staat, terwijl je alles behandeld als UTF-8, terwijl je dat gemakshalve vergeten bent bij het maken van de connectie.
Gewijzigd op 31/03/2018 13:58:39 door Thomas van den Heuvel
@Ariën: dank, ik ga het omzetten naar een methode.
Dank allen voor de feedback. top
Jan te Pas op 31/03/2018 14:59:53:
Ik heb overal een standaard kop met daarin de charactercoding.
Maar dat alleen is niet genoeg. Hoe je de bestanden opslaat kan ook van belang zijn als hier bijvoorbeeld speciale symbolen in zitten.
Bijvoorbeeld het copyright karakter ©.
Als je het bestand opslaat als ISO-8859-1 dan heeft dit karakter de (hexadecimale) codering A9.
Als je het bestand opslaat als UTF-8 dan heeft dit karakter de (hexadecimale) codering C2A9.
Wanneer je nu het bestand opslaat als ISO-8859-1 maar serveert als UTF-8 (of andersom) dan kan dit (ver)taalfouten opleveren.
En dan wordt het nog wat complexer als je ook nog eens praat met een database. Lees daarom goed het verhaal in de voorgaande link door en stel ook vooral een character encoding in na het maken van een connectie (middels set_charset()) die reflecteert hoe je je documenten serveert. Gebruik je ISO-8859-1 kies dan latin1, gebruik je UTF-8 kies dan utf8 of equivalent. Et cetera.
EDIT: daarnaast is het belangrijk dat je in *alle* contexten escaped, dus naast de (My)SQL-context (via real_escape_string()) ook in de HTML-context (via htmlspecialchars()). Ook in deze laatstgenoemde functie spelen character encoderingen een rol (zie derde parameter).
Gewijzigd op 31/03/2018 17:31:51 door Thomas van den Heuvel
Thomas van den Heuvel op 31/03/2018 17:13:37:
Maar dat alleen is niet genoeg. Hoe je de bestanden opslaat kan ook van belang zijn als hier bijvoorbeeld speciale symbolen in zitten.
Bijvoorbeeld het copyright karakter ©.
Als je het bestand opslaat als ISO-8859-1 dan heeft dit karakter de (hexadecimale) codering A9.
Als je het bestand opslaat als UTF-8 dan heeft dit karakter de (hexadecimale) codering C2A9.
Wanneer je nu het bestand opslaat als ISO-8859-1 maar serveert als UTF-8 (of andersom) dan kan dit (ver)taalfouten opleveren.
En dan wordt het nog wat complexer als je ook nog eens praat met een database. Lees daarom goed het verhaal in de voorgaande link door en stel ook vooral een character encoding in na het maken van een connectie (middels set_charset()) die reflecteert hoe je je documenten serveert. Gebruik je ISO-8859-1 kies dan latin1, gebruik je UTF-8 kies dan utf8 of equivalent. Et cetera.
Jan te Pas op 31/03/2018 14:59:53:
Ik heb overal een standaard kop met daarin de charactercoding.
Maar dat alleen is niet genoeg. Hoe je de bestanden opslaat kan ook van belang zijn als hier bijvoorbeeld speciale symbolen in zitten.
Bijvoorbeeld het copyright karakter ©.
Als je het bestand opslaat als ISO-8859-1 dan heeft dit karakter de (hexadecimale) codering A9.
Als je het bestand opslaat als UTF-8 dan heeft dit karakter de (hexadecimale) codering C2A9.
Wanneer je nu het bestand opslaat als ISO-8859-1 maar serveert als UTF-8 (of andersom) dan kan dit (ver)taalfouten opleveren.
En dan wordt het nog wat complexer als je ook nog eens praat met een database. Lees daarom goed het verhaal in de voorgaande link door en stel ook vooral een character encoding in na het maken van een connectie (middels set_charset()) die reflecteert hoe je je documenten serveert. Gebruik je ISO-8859-1 kies dan latin1, gebruik je UTF-8 kies dan utf8 of equivalent. Et cetera.
Thomas, dank je wel voor deze bijles! Op naar betere sources!
Zie ook toevoeging in eerdere bericht. In alle contexten zou je moeten filteren en escapen, dit wordt ook wel verwoord in de vuistregel "filter input, escape output".