Verwerken van bedrijfsnaam met speciale leestekens
Ik ben bezig met een CRM aan het ontwikkelen en ik loop tegen het bedrijfsnaam aan tegen, ik kan hem niet verwerken binnen de database. Hoe kan ik dit tackelen? want het weergeven van alle bedrijfsinformatie gaat via bedrijfsnaam en de enkele en dubbele quotes snijden dan de string af. Hier zijn diverse voorbeelden;
v.v. d´Olde Veste ´54
Mini camping "Onder" de Heerenbrug
Bierproeverij ' de Beijerlandse Biersommelier '
ik probeerde het met preg_match :
Graag advies.
Gewijzigd op 03/01/2023 11:16:06 door P Wever
Gewijzigd op 03/01/2023 11:52:22 door - Ariën -
' en " word nu vervangen met ` en alle data word nu escaped.
dus het is opgelost.
P Wever op 03/01/2023 13:36:01:
Ik heb het toegepast en ook wat veranderd bij het aanmaken van nieuwe klant;
' en " word nu vervangen met ` en alle data word nu escaped.
dus het is opgelost.
' en " word nu vervangen met ` en alle data word nu escaped.
dus het is opgelost.
Ik zie geen reden om de tekst aan te passen. De escape-functie zorgt dat _in_ de query voor de ' een \ komt te staan. Daarmee gaat die prima de database in.
Door er een ander teken van te maken, los je het hier op, maar mogelijk niet op 20 andere plekken en je applicatie: met escapen krijg je alles gewoon 1 op 1 in je database.
Als je het aanpast, komt er een moment dat het bij het ophalen weer mis gaat: iets staat tussen 2 van de scheven "apostrofjes" (wat er niet uitziet) of bij vergelijken lijkt het of een bedrijfsnaam nog niet aanwezig is, omdat bij het vergelijken een ' en een ` echt anders zijn.
Dus: ja, het "werkt" want je krijgt geen foutmelding. Maar dat wil niet zeggen dat dat een goede weg is om te bewandelen.
Toevoeging op 03/01/2023 20:52:03:
(en zeker in een CRM wil je niet je klanten tegen de haren in strijken door hun namen aan te passen, omdat JIJ niet om kan gaan met niet-heel-bijzondere karakters in een naam)
Ivo P op 03/01/2023 20:49:58:
Ik zie geen reden om de tekst aan te passen. De escape-functie zorgt dat _in_ de query voor de ' een \ komt te staan. Daarmee gaat die prima de database in.
Door er een ander teken van te maken, los je het hier op, maar mogelijk niet op 20 andere plekken en je applicatie: met escapen krijg je alles gewoon 1 op 1 in je database.
Als je het aanpast, komt er een moment dat het bij het ophalen weer mis gaat: iets staat tussen 2 van de scheven "apostrofjes" (wat er niet uitziet) of bij vergelijken lijkt het of een bedrijfsnaam nog niet aanwezig is, omdat bij het vergelijken een ' en een ` echt anders zijn.
Dus: ja, het "werkt" want je krijgt geen foutmelding. Maar dat wil niet zeggen dat dat een goede weg is om te bewandelen.
Toevoeging op 03/01/2023 20:52:03:
(en zeker in een CRM wil je niet je klanten tegen de haren in strijken door hun namen aan te passen, omdat JIJ niet om kan gaan met niet-heel-bijzondere karakters in een naam)
P Wever op 03/01/2023 13:36:01:
Ik heb het toegepast en ook wat veranderd bij het aanmaken van nieuwe klant;
' en " word nu vervangen met ` en alle data word nu escaped.
dus het is opgelost.
' en " word nu vervangen met ` en alle data word nu escaped.
dus het is opgelost.
Ik zie geen reden om de tekst aan te passen. De escape-functie zorgt dat _in_ de query voor de ' een \ komt te staan. Daarmee gaat die prima de database in.
Door er een ander teken van te maken, los je het hier op, maar mogelijk niet op 20 andere plekken en je applicatie: met escapen krijg je alles gewoon 1 op 1 in je database.
Als je het aanpast, komt er een moment dat het bij het ophalen weer mis gaat: iets staat tussen 2 van de scheven "apostrofjes" (wat er niet uitziet) of bij vergelijken lijkt het of een bedrijfsnaam nog niet aanwezig is, omdat bij het vergelijken een ' en een ` echt anders zijn.
Dus: ja, het "werkt" want je krijgt geen foutmelding. Maar dat wil niet zeggen dat dat een goede weg is om te bewandelen.
Toevoeging op 03/01/2023 20:52:03:
(en zeker in een CRM wil je niet je klanten tegen de haren in strijken door hun namen aan te passen, omdat JIJ niet om kan gaan met niet-heel-bijzondere karakters in een naam)
' De escape-functie zorgt dat _in_ de query voor de ' een \ komt te staan. Daarmee gaat die prima de database in.'
Omdat dit niet eruit ziet, dit word weergegeven op de dashboard en moet ook op kunnen worden gezocht. Dus als voorbeeld "V.v. d `Olde Veste `54" en niet "V.v. d \`Olde Veste \`54", daardoor kan ik letterlijk record niet ophalen. dus dat breekt meer dan het goed doet.
Dus als je daarvoor iets weet hoor ik het graag.
Ikzelf gebruik altijd mysqli_real_escape_string() of de equivalent real_escape_string(), en ik hoef nergens op te filteren. Alles wat op ik haal met vreemde tekens, is zoals het hoort. Dus blijkbaar pas jij het verkeerd toe?
Gewijzigd op 04/01/2023 12:09:33 door - Ariën -
Even een simpel voorbeeld: het euroteken wordt met htmlentities() vertaald naar € . Dat is ook een soort van escaping.
Maar wat ziet iemand die de html-pagina bekijkt? Gewoon het euroteken.
Nu naar je query: stel jij wilt "d'olde veste" opslaan.
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
$naam = "d'olde veste';
$naam_esc = $this-db->escape($naam);
$query = "INSERT INTO tabel (naam) VALUES ('$naam_esc')";
// nu is $query dus INSERT INTO tabel (naam) VALUES ('d\'olde veste')
?>
$naam = "d'olde veste';
$naam_esc = $this-db->escape($naam);
$query = "INSERT INTO tabel (naam) VALUES ('$naam_esc')";
// nu is $query dus INSERT INTO tabel (naam) VALUES ('d\'olde veste')
?>
De query stuur je naar je database. Deze database moet je query interpreteren.
Hij weet dat values tussen ' ' zullen staan.
Had er geen \ voor de ' die na de letter d komt, dan had hij die ' gezien als een einde van een value en daarna een foutmelding gegeven omdat hij de rest van de tekst niet meer begrijpt.
Maar vanwege \' snapt hij dat die ' niet een "einde value" betekenis heeft, maar dat deze ' gewoon letterlijk een ' is.
En vervolgens komt er dus in je database gewoon "d'olde veste" te staan.
(vergelijk het met het euroteken)
Die \ is dus een teken dat alleen maar een aanwijzing is voor je database.
"vroeger" had je nog van die "magic-quotes" waarbij PHP zelf ook al \ ging toevoegen, en dan kreeg je "soms" inderdaad \ in de database als je daarna ook nog de database escape functie gebruikt. Maar die setting is gelukking intussen al een jaar of 10 verleden tijd.
NB
ik gebruik $this-db->escape() maar daar moet je de escape functie gebruik van jouw database class, of gewoon mysqli_real_escape_string()
Toevoeging op 04/01/2023 12:18:49:
Probeer het eens, en kijk daarna wat er werkelijk in je database terecht is gekomen.
Ik heb het idee dat je de query op het scherm hebt gezet en daarna zelf de conclusie hebt getrokken dat het mis zal gaan.
- Ariën - op 04/01/2023 12:07:38:
Ik ben eerder benieuwd hoe je dat toepast.
Ikzelf gebruik altijd mysqli_real_escape_string() of de equivalent real_escape_string(), en ik hoef nergens op te filteren. Alles wat op ik haal met vreemde tekens, is zoals het hoort. Dus blijkbaar pas jij het verkeerd toe?
Ikzelf gebruik altijd mysqli_real_escape_string() of de equivalent real_escape_string(), en ik hoef nergens op te filteren. Alles wat op ik haal met vreemde tekens, is zoals het hoort. Dus blijkbaar pas jij het verkeerd toe?
Zodra ik maar iets in de query moet verwerken; gaat de data eerst door mijn functie 'bedrijfsnaam' wat niks anders is dan preg_match en controleren voor 2 tekens en indien aanwezig vervangen met `.Ik pas hierna mysqli_real_escape_string() toe (Ik heb er een functie van gemaakt clearinput voor in mijn class) voordat ik het toesta dat die gebruikt word in de query.
ik zal kleine snippets plaatsen
controleren of er gepost word en in die brackets heb ik deze controle;
Code (php)
1
2
3
4
2
3
4
if(!$system->bedrijfsnaam($_POST['bedrijfsnaam'])){
$error = true;
$errormsg = "Bedrijfsnaam is niet geldig enkel a-z A-z 0-9 ` . , - _ toegestaan.";
}
$error = true;
$errormsg = "Bedrijfsnaam is niet geldig enkel a-z A-z 0-9 ` . , - _ toegestaan.";
}
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
function bedrijfsnaam($string){
$newstring = str_replace(array('"', '\''), '`', $string);
if(preg_match("#^[a-zA-Z0-9.,-_` ]+$#", $newstring)){
return $newstring;
} else {
return false;
}
}
$newstring = str_replace(array('"', '\''), '`', $string);
if(preg_match("#^[a-zA-Z0-9.,-_` ]+$#", $newstring)){
return $newstring;
} else {
return false;
}
}
Code (php)
1
2
3
4
5
2
3
4
5
function clearinput($input){
if(!empty($input)){
return mysqli_real_escape_string($this->db_connect(), $input);
}
}
if(!empty($input)){
return mysqli_real_escape_string($this->db_connect(), $input);
}
}
Hopelijk is dat duidelijk genoeg, zo niet vraag het.
Ik ben bang dat dit op een verkeerde plek zal zijn waardoor je juist jouw data om zeep helpt
Dit hoor je toe te passen binnen een query.
Code (php)
Zie ook de voorbeelden op:
https://github.com/arienclaij/sql-boilerplate/tree/master/mysqli/oo
Gewijzigd op 04/01/2023 12:28:27 door - Ariën -
- Ariën - op 04/01/2023 12:27:51:
Waar pas je de clearinput() functie toe?
Ik ben bang dat dit op een verkeerde plek zal zijn.
Dit hoor je toe te passen binnen een query.
Zie ook de voorbeelden op:
https://github.com/arienclaij/sql-boilerplate/tree/master/mysqli/oo
Ik ben bang dat dit op een verkeerde plek zal zijn.
Dit hoor je toe te passen binnen een query.
Code (php)
Zie ook de voorbeelden op:
https://github.com/arienclaij/sql-boilerplate/tree/master/mysqli/oo
Ik pas het ervoor toe op de input, maar dan doe ik het inderdaad verkeerd haha.
Ik heb het nu zo staan :
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
$nieuwe_klant = mysqli_query($db->db_connect(), "INSERT INTO klanten (adress, postcode, provincie, land, ingangsdatum, email, factuuremail, `user_id`, voornaam, achternaam, telefoonnummer, bedrijfsnaam, kvk, btw, klantnummer, plaats) values
('".$db->clearinput($_POST['straat'])." ".$db->clearinput($_POST['huisnummer'])."',
'".$db->clearinput($_POST['postcode'])."',
'".$db->clearinput($_POST['provincie'])."',
'Nederland',
'".$date."',
'".$db->clearinput($_POST['email'])."',
'".$db->clearinput($_POST['factuuremail'])."',
'".$id."',
'".$db->clearinput($_POST['voornaam'])."',
'".$db->clearinput($_POST['achternaam'])."',
'".$db->clearinput($_POST['telefoonnummer'])."',
'".$db->clearinput($bedrijfsnaam)."',
'".$db->clearinput($_POST['kvk'])."',
'".$db->clearinput($_POST['btw'])."',
'".$klantnummer."',
'".$db->clearinput($_POST['stad'])."' )");
?>
$nieuwe_klant = mysqli_query($db->db_connect(), "INSERT INTO klanten (adress, postcode, provincie, land, ingangsdatum, email, factuuremail, `user_id`, voornaam, achternaam, telefoonnummer, bedrijfsnaam, kvk, btw, klantnummer, plaats) values
('".$db->clearinput($_POST['straat'])." ".$db->clearinput($_POST['huisnummer'])."',
'".$db->clearinput($_POST['postcode'])."',
'".$db->clearinput($_POST['provincie'])."',
'Nederland',
'".$date."',
'".$db->clearinput($_POST['email'])."',
'".$db->clearinput($_POST['factuuremail'])."',
'".$id."',
'".$db->clearinput($_POST['voornaam'])."',
'".$db->clearinput($_POST['achternaam'])."',
'".$db->clearinput($_POST['telefoonnummer'])."',
'".$db->clearinput($bedrijfsnaam)."',
'".$db->clearinput($_POST['kvk'])."',
'".$db->clearinput($_POST['btw'])."',
'".$klantnummer."',
'".$db->clearinput($_POST['stad'])."' )");
?>
Toevoeging op 04/01/2023 12:47:48:
Ik heb nu de escape string op juiste plek staan en nu kan ik de bedrijfsnamen dat ik als eerst benoemde gewoon verwerken en ophalen!
Gewijzigd op 04/01/2023 13:24:44 door P Wever
Je sloot C&A, Hunkemöller en Me@Work4U uit omdat er "rare" tekens in de naam voorkwamen.
Bedrijfsnaam
Company Name
???????? ???????????
???? ??????
Företagsnamn
Ettevõtte nimi
????????? ??????
??? ?????
Toevoeging op 04/01/2023 14:17:01:
Nou php hulp, dat schiet ook niet op.
Alleen Latijnse letters worden ondersteund.
Ruwweg:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
$naam = $_POST['bedrijfsnaam'] or return [-1, 'Bedrijfsnaam mag niet leeg zijn'];
$mysqli = new mysqli($hostname, $dbuser, $dbpass, $dbname);
$stmt = $mysqli->stmt_init();
$stmt->prepare("INSERT INTO tabel (naam) VALUES (?)");
$stmt->bind_param("s", $naam);
$stmt->execute();
?>
$naam = $_POST['bedrijfsnaam'] or return [-1, 'Bedrijfsnaam mag niet leeg zijn'];
$mysqli = new mysqli($hostname, $dbuser, $dbpass, $dbname);
$stmt = $mysqli->stmt_init();
$stmt->prepare("INSERT INTO tabel (naam) VALUES (?)");
$stmt->bind_param("s", $naam);
$stmt->execute();
?>
Geen gedoe met real_escape_string() en zo, je bent immuun voor SQL-injectie, en je statement is herbruikbaar, wat scheelt in performance als je het statement meerdere malen moet uitvoeren.
Gewijzigd op 05/01/2023 23:33:10 door Willem vp