Verwerken van bedrijfsnaam met speciale leestekens

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

P Wever

P Wever

03/01/2023 11:14:53
Quote Anchor link
Beste,

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 :
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if(!preg_match("[^a-zA-Z0-9 \"\'\?\-]", $_POST['bedrijfsnaam'])){



Graag advies.
Gewijzigd op 03/01/2023 11:16:06 door P Wever
 
PHP hulp

PHP hulp

24/11/2024 17:19:32
 
Adoptive Solution

Adoptive Solution

03/01/2023 11:44:36
Quote Anchor link
Gebruik dit. Oefen met alle mogelijk combinaties.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$naam = $db->real_escape_string( $_POST['naam'] );
 
- Ariën  -
Beheerder

- Ariën -

03/01/2023 11:51:53
Quote Anchor link
$db->real_escape_string(......) moet je ALTIJD toepassen bij het gebruik van manipulatieve data (zoals POST, GET, COOKIE) in een query. Het beschermt je query tegen corruptie vanuit bepaalde tekens (denk aan bijv. de apostrof '), en dus ook tegen SQL-injection. Dus als je bijvoorbeeld 's-Gravenzande niet ingevoerd krijgt. Dan weet je dat je deze belangrijke regel mist!
Gewijzigd op 03/01/2023 11:52:22 door - Ariën -
 
P Wever

P Wever

03/01/2023 13:36:01
Quote Anchor link
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.
 
Ivo P

Ivo P

03/01/2023 20:49:58
Quote Anchor link
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.


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

P Wever

04/01/2023 11:50:54
Quote Anchor link
Ivo P op 03/01/2023 20:49:58:
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.


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.
 
- Ariën  -
Beheerder

- Ariën -

04/01/2023 12:07:38
Quote Anchor link
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?
Gewijzigd op 04/01/2023 12:09:33 door - Ariën -
 
Ivo P

Ivo P

04/01/2023 12:16:58
Quote Anchor link
Nee, zo werkt dat escapen niet.

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)
PHP script in nieuw venster Selecteer het PHP script
1
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')

?>


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.
 
P Wever

P Wever

04/01/2023 12:21:09
Quote Anchor link
- 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?


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)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
if(!$system->bedrijfsnaam($_POST['bedrijfsnaam'])){
   $error = true;
   $errormsg = "Bedrijfsnaam is niet geldig enkel a-z A-z 0-9 ` . , - _ toegestaan.";    
}


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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;
  }
}


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
function clearinput($input){
if(!empty($input)){
  return mysqli_real_escape_string($this->db_connect(), $input);
}
}


Hopelijk is dat duidelijk genoeg, zo niet vraag het.
 
- Ariën  -
Beheerder

- Ariën -

04/01/2023 12:27:51
Quote Anchor link
Waar pas je de clearinput() functie toe?
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)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
sQuery = "
            SELECT
                name,
                job,
                rank
            FROM
                users
            WHERE
                name = '"
.$sqlLink->escape_string(ucfirst(trim($_POST['naam'])))."'
            "
;
$result = $sqlLink->query($sQuery);
?>

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 -
 
P Wever

P Wever

04/01/2023 12:28:31
Quote Anchor link
- 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.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
sQuery = "
            SELECT
                name,
                job,
                rank
            FROM
                users
            WHERE
                name = '"
.$sqlLink->escape_string(ucfirst(trim($_POST['naam'])))."'
            "
;
$result = $sqlLink->query($sQuery);
?>

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)
PHP script in nieuw venster Selecteer het PHP script
1
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'])."' )");
?>



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
 
Ivo P

Ivo P

04/01/2023 14:04:04
Quote Anchor link
precies: en dus niet zelf tekens gaan definieren die in een naam voor mogen komen.
Je sloot C&A, Hunkemöller en Me@Work4U uit omdat er "rare" tekens in de naam voorkwamen.
 
Adoptive Solution

Adoptive Solution

04/01/2023 14:15:59
Quote Anchor link
Nog een paar bedrijfsnamen :

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.
 
Willem vp

Willem vp

05/01/2023 22:39:09
Quote Anchor link
In deze discussie mis ik de -mijns inziens beste- oplossing met prepared statements.

Ruwweg:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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();
?>


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
 



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.