login  Naam:   Wachtwoord: 
Registreer je!
 Forum

utf-8 database/documenten/charset slaat geen html op? (Opgelost)

Offline vinTage - 16/12/2013 19:59 (laatste wijziging 16/12/2013 20:07)
Avatar van vinTageNieuw lid Ik heb mijn database ingesteld op utf-8 middels:
  1. mysql_query('SET NAMES utf8');


In mijn html formuliertje heb ik een select met de volgende options:
  1. <option value="m&sup1;"<?php if($item_eenheid == 'm&sup1;'){echo ' selected="selected"';}?>>m&sup1;</option>
  2. <option value="m&sup2;"<?php if($item_eenheid == 'm&sup2;'){echo ' selected="selected"';}?>>m&sup2;</option>

Nu denk je "wat die die php ertussen?", maar daar kom ik zo op terug.

Het posten/opslaan naar de database gaat zo: (de [$key] staat erbij, omdat ik items 'on the fly' kan bijmaken (ajax)
  1. '".trim(mysql_real_escape_string($_POST['eenheid'][$key]))."'


Enfin, dit werkt allemaal zonder problemen, alleen komt er in de database die eenheid als volgt te staan (ook als je die cel wilt aanpassen):
m¹ ipv m&sup1;
m² ipv m&sup2;

Dit heeft dus vervelende gevolgen, want nu kan ik niet in php controleren of een waarde al dan niet hetzelfde is, zoals in het stukje php van het formuliertje, wat ik tevens gebruik om formulieren aan te passen en bijhorende option dus selected moet komen te staan.

Het rare verder, is dat als ik de source bekijk (ctrl + u) dat daar WEL m&sup1; en m&sup2; staat..... Als ik via firebug controleer, dan staat er m¹ en m² bij de option meuk....

Het uitlezen van de database, doe ik altijd via htmlentities, maar htmlspecialchars en zelfde de 'pure' output matchen nooit met wat er in de db staan?!

Weet iemand wat ik verkeerd doe..?

28 antwoorden

Gesponsorde links
Offline markla - 16/12/2013 20:16
Avatar van markla PHP interesse Je heb nu
  1. mysql_query('SET NAMES utf8');

in je script staan

Maar zelf had ik ook onlangs zoiets toen heb ik <meta charset="utf-8"> aan de index toegevoegd en het probleem was verholpen.

hopelijk is ook dat ook voor jou de oplossing

Offline vinTage - 16/12/2013 20:21 (laatste wijziging 16/12/2013 20:22)
Avatar van vinTage Nieuw lid Voor de zekerheid toch maar even getest.
Al heb ik dit er al instaan:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">


Maar je tip werkt ook niet.

Ik heb ook nog een php header erin staan (gedaan om te testen) maar dat hielp ook niet:
header("Content-Type: text/html; charset=utf-8");

Toch bedankt voor het meedenken, maar ik denk dat echt alles al utf-8 is 
Offline Thomas - 16/12/2013 20:57
Avatar van Thomas Moderator Lijkt mij een weergave-aangelegenheid? Waarmee bekijk je de data in je database? Via een MySQL-console? Via phpMyAdmin? Iets anders? En hoe luidt je character-set daar? Hoe ziet je INSERT/UPDATE query er uit (dump deze eens ergens naartoe)? En weet je zeker dat er niet iets fout gaat in je vergelijking?

En als dit alles geen soelaas biedt, maak een tabel aan met eenheid-types, dan kun je vergelijken op id's en hoef je niets te vergelijken met de manier waarop je het wilt weergeven... Al snap ik niet dat dit mis kan gaan... Mogelijk is iets dubbel UTF-8 gecodeerd?
Offline vinTage - 16/12/2013 21:11 (laatste wijziging 16/12/2013 21:16)
Avatar van vinTage Nieuw lid Ik gebruik PMA waarmee ik de data bekijk, maar daar staat echt m¹ ipv m&sup1; zowel via firebug als via view source 

De insert (de update heb ik nog niet want ik loop vast omdat de selects niet werken bij die &sup1; enz), gaat als volgt:

  1. if(isset($_POST['opslaan']))
  2. {
  3. $factuurnummer = $_POST['status'] == 1 ? trim(mysql_real_escape_string($_POST['status'])) : 0;
  4. "insert into facturen
  5. (factuurnummer, status, datum, naam, straatnaam, huisnummer, postcode, woonplaats, telefoon, gsm, email, factuurnaam,factuurstraatnaam,factuurhuisnummer,factuurpostcode,factuurwoonplaats, factuurtelefoon,factuurgsm,factuuremail)
  6. values
  7. (
  8. '".$factuurnummer."',
  9. '".trim(mysql_real_escape_string($_POST['status']))."',
  10. '".trim(mysql_real_escape_string(date('Y-m-d',$_POST['datum'])))."',
  11. '".trim(mysql_real_escape_string($_POST['naam']))."',
  12. '".trim(mysql_real_escape_string($_POST['straatnaam']))."',
  13. '".trim(mysql_real_escape_string($_POST['huisnummer']))."',
  14. '".trim(mysql_real_escape_string($_POST['postcode']))."',
  15. '".trim(mysql_real_escape_string($_POST['woonplaats']))."',
  16. '".trim(mysql_real_escape_string($_POST['telefoon']))."',
  17. '".trim(mysql_real_escape_string($_POST['gsm']))."',
  18. '".trim(mysql_real_escape_string($_POST['email']))."',
  19. '".trim(mysql_real_escape_string($_POST['factuurnaam']))."',
  20. '".trim(mysql_real_escape_string($_POST['factuurstraatnaam']))."',
  21. '".trim(mysql_real_escape_string($_POST['factuurhuisnummer']))."',
  22. '".trim(mysql_real_escape_string($_POST['factuurpostcode']))."',
  23. '".trim(mysql_real_escape_string($_POST['factuurwoonplaats']))."',
  24. '".trim(mysql_real_escape_string($_POST['factuurtelefoon']))."',
  25. '".trim(mysql_real_escape_string($_POST['factuurgsm']))."',
  26. '".trim(mysql_real_escape_string($_POST['factuuremail']))."'
  27. )")or die(mysql_error());
Waarbij factuurnummer een prefix en volgnummer weergeeft, dus niet belangrijk voor deze vraag
Ik heb elke tabel en de database staan op utf_unicode_ci, maar daarnaast (net gedaan) zet ik alles nog eens on the fly op utf-8, en 'onderstaande' echo-ed dan ook effectief utf8.
  1. //utf-8 meuk testzooi
  2. mysql_query('SET NAMES utf8');
  3. if (!mysql_set_charset('utf8')) {
  4. echo "Error: Unable to set the character set.\n";
  5. }
  6. echo mysql_client_encoding(); //geeft echt utf8


Die vergelijking met eenheid types had ikzelf ook verzonnen, maar ik vind (mocht het werken...) de manier zoals ik probeer toch leuker 

Citaat:
Mogelijk is iets dubbel UTF-8 gecodeerd?
Hmm, dat zou zomaar kunnen, maar geen idee hoe je zoiets kan doen, utf-8 is toch gewoon utf-8 ?

edit, die set names even weggehaald en die set_charset alleen gedaan, maar alles blijft bij het oude.
Ik zal hier een test code plempen incl db dumpje
Offline Thomas - 16/12/2013 21:27
Avatar van Thomas Moderator Er staat mij niet bij dat ampersands door de mangel worden gehaald bij inserts, utf-8 zou hier verder vanaf moeten blijven toch? Hoe is de database/tabel gedefinieerd (met welke charset)? En heb je toevallig de waarde van $item_eenheid al eens ergens gedumpt? 
Bedankt door: vinTage
Offline vinTage - 16/12/2013 21:33 (laatste wijziging 16/12/2013 21:51)
Avatar van vinTage Nieuw lid Ik ben een dikke gestripte versie aan het maken voor diegene die zelf willen testen (nog 10 mins oid voor em klaar is).
Maar ik ga nu idd EERST je voorstel testen (de dump )

edit: arf...die geeft m¹ (ook in de source) :S

Okidokie, op zoek naar 'die' blunder dus 

Edit2:
Ook met mn MEGA simpele versie blijft het foutgaan...
Bij deze de gehele (test) code:
  1. --
  2. -- Tabel structuur voor tabel `test_facturen`
  3. --
  4.  
  5. CREATE TABLE `test_facturen` (
  6. `id` int(11) NOT NULL AUTO_INCREMENT,
  7. `items_value` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  8. PRIMARY KEY (`id`)
  9. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
  10.  
  11. --
  12. -- Gegevens worden uitgevoerd voor tabel `test_facturen`
  13. --


  1. <?php
  2. mysql_connect ('localhost', 'root', 'geheimpje');
  3. mysql_select_db('WHATEVER');
  4. //utf-8 meuk testzooi
  5. //mysql_query('SET NAMES utf8');
  6. if (!mysql_set_charset('utf8')) {
  7. echo "Error: Unable to set the character set.\n";
  8. }
  9. //echo mysql_client_encoding(); //utf8
  10.  
  11. if(isset($_POST['opslaan']))
  12. {
  13. mysql_query("insert into test_facturen (items_value)
  14. values ('".trim(mysql_real_escape_string($_POST['items']))."')")or die(mysql_error());
  15. header('location: ?aanpassen='.mysql_insert_id());
  16. }
  17. ?>
  18. <!DOCTYPE html>
  19. <html lang="nl">
  20. <head>
  21. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  22. <title>test</title>
  23. </head>
  24. <body>
  25. <?php
  26. $item_eenheid = '';
  27. if(isset($_GET['aanpassen']))
  28. {
  29. $qry = mysql_query("select items_value from test_facturen where id = ".mysql_real_escape_string($_GET['aanpassen']))or die(mysql_error());
  30. while($res = mysql_fetch_assoc($qry))
  31. {
  32. $item_eenheid = stripslashes(htmlentities($res['items_value'])); //maar ook 'puur' lukt het niet (dus zonder stripslashes en htmlentities)
  33. }
  34. }
  35. ?>
  36. <form action="" method="post">
  37. <select name="items">
  38. <option value="">eenheid</option>
  39. <option value="m&sup1;"<?php if($item_eenheid == 'm&sup1;'){echo ' selected="selected"';}?>>m&sup1;</option>
  40. <option value="m&sup2;"<?php if($item_eenheid == 'm&sup2;'){echo ' selected="selected"';}?>>m&sup2;</option>
  41. <option value="uur"<?php if($item_eenheid == 'uur'){echo ' selected="selected"';}?>>uur</option>
  42. </select>
  43. <input name="opslaan" type="submit" value="opslaan">
  44. </form>
  45. </body>
  46. </html>
Offline Thomas - 16/12/2013 21:57
Avatar van Thomas Moderator Maar de htmlentities van & is toch &amp; ? 

Als er dus "m&sup1;" in je database staat (wat ik eigenlijk gewoon verwacht), en je gooit hier htmlentities overheen wordt dit "m&amp;sup1;"?

Of is het toch ingewikkelder dan dat?

Als je deze waarde edit zul je hem wss wel in htmlentities-vorm moeten afdrukken (dan staat er dus in de source &amp;, maar als je deze opslaat wordt dit wss weer braaf een "&").

Vaagheid. Ben benieuwd naar de mysqldump? En maak anders eens een verbinding via een prompt als je dit kan / weet hoe?
Offline vinTage - 16/12/2013 22:01 (laatste wijziging 16/12/2013 22:05)
Avatar van vinTage Nieuw lid Als ik htmlentities etc weghaal (dus 'puur uit de db haal=> zonder een andere php functie') dan klopt het nog altijd niet (maar je hebt wel een punt!)
Helaas weet ik TOTAAL niet hoe ik die db anders bereik dan middels pma 

Edit: bij deze een dump van 'testfacturen'

  1. CREATE TABLE `test_facturen` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `items_value` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  4. PRIMARY KEY (`id`)
  5. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;
  6.  
  7. --
  8. -- Gegevens worden uitgevoerd voor tabel `test_facturen`
  9. --
  10.  
  11. INSERT INTO `test_facturen` (`id`, `items_value`) VALUES
  12. (1, 'm¹'),
  13. (2, 'm²'),
  14. (3, 'm¹'),
  15. (4, 'm¹');

edit2: het is dus dat er GEEN m&sup1; in de db terecht komt, DAT is mijn probleem 
Offline Thomas - 16/12/2013 22:36 (laatste wijziging 16/12/2013 22:39)
Avatar van Thomas Moderator escape de values, oftewel
<option value="m&amp;sup1;">...

etc.

Dat zou moeten werken.

Let ook op caching van pagina's, als je naar de source kijkt werkt de selected, alleen dit zie je mogelijk niet direct terug in je dropdown (dat de goede value is geselecteerd).

edit: mogelijk moet je ook accept-charset="utf-8" toevoegen in je form tag?
edit: en die htmlentities() er ook uit in regel 34 van je gestripte versie uiteraard. Want je vergelijk nog met & in de ==, niet met &amp;
Offline vinTage - 16/12/2013 22:43 (laatste wijziging 16/12/2013 22:48)
Avatar van vinTage Nieuw lid Hmm, heb je mijn 'test' code uitgevoerd, want zelfs met dat 'escapen' krijg ik het niet voor elkaar?
Ik kijk sowieso elke keer met firebug en in de source, maar (zelfs na cache legen) blijf ik dit geze*k houden.

Iig thx dat je je kundige blik werpt hoor!
Maar voor mezelf ben ik er nog niet uit (en wil die optie met 'mogelijkheden en terug vergelijken (nog) niet toepassen #eigenwijsdatikben )


edit:
oh, even doen wat je net voorstelt @ accept dinges! (en natuurlijk probeer ik het met/zonder 'veilige' functies 
edit2: accept dinges ook geen effect 
Offline Thomas - 16/12/2013 22:56 (laatste wijziging 16/12/2013 23:00)
Avatar van Thomas Moderator Dit werkt bij mij?

  1. <?php
  2. mysql_connect ('localhost', 'lala', 'lala');
  3. //utf-8 meuk testzooi
  4. //mysql_query('SET NAMES utf8');
  5. if (!mysql_set_charset('utf8')) {
  6. echo "Error: Unable to set the character set.\n";
  7. }
  8. //echo mysql_client_encoding(); //utf8
  9.  
  10. if(isset($_POST['opslaan']))
  11. {
  12. $query = "insert into test_facturen (items_value)
  13. values ('".trim(mysql_real_escape_string($_POST['items']))."')";
  14. header('location: ?aanpassen='.mysql_insert_id());
  15. }
  16. ?>
  17. <!DOCTYPE html>
  18. <html lang="nl">
  19. <head>
  20. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  21. <title>test</title>
  22. </head>
  23. <body>
  24. <?php
  25. $item_eenheid = '';
  26. if(isset($_GET['aanpassen']))
  27. {
  28. $qry = mysql_query("select items_value from test_facturen where id = ".mysql_real_escape_string($_GET['aanpassen']))or die(mysql_error());
  29. while($res = mysql_fetch_assoc($qry))
  30. {
  31. // HTMLENTITIES WEG!
  32. $item_eenheid = stripslashes($res['items_value']); //maar ook 'puur' lukt het niet (dus zonder stripslashes en htmlentities)
  33. }
  34. }
  35. // EN HIERONDER DUS & ESCAPEN (&amp; IPV &)
  36. ?>
  37. <form action="" method="post" accept-charset="utf-8">
  38. <select name="items">
  39. <option value="">eenheid</option>
  40. <option value="m&amp;sup1;"<?php if($item_eenheid == 'm&sup1;'){ echo ' selected="selected"';}?>>m&sup1;</option>
  41. <option value="m&amp;sup2;"<?php if($item_eenheid == 'm&sup2;') {echo ' selected="selected"';}?>>m&sup2;</option>
  42. <option value="uur"<?php if($item_eenheid == 'uur'){echo ' selected="selected"';}?>>uur</option>
  43. </select>
  44. <input name="opslaan" type="submit" value="opslaan">
  45. </form>
  46. </body>
  47. </html>


Maar 3 wijzigingen dus (htmlentities weg, &amp; ipv & en accept-charset).

Waarschijnlijk is alleen die escaping nodig, verder niets.

Kijk eens naar je source, daar staat wellicht wel selected="selected", ook al zie je dit niet weergegeven in je select.

  1. mysql> SELECT * FROM test_facturen;
  2. +----+-------------+
  3. | id | items_value |
  4. +----+-------------+
  5. | 1 || <-- mja toen was die & --> &amp; nog niet aangepast :s
  6. | 2 | m&sup1; |
  7. | 3 | m&sup2; |
  8. | 4 | uur |
  9. +----+-------------+
  10. 4 rows IN SET (0.00 sec)
Bedankt door: vinTage
Offline vinTage - 16/12/2013 23:04
Avatar van vinTage Nieuw lid ENORM bedankt, je code lijkt te werken!

Ik weet nog niet welke 'onderdeel' precies de fout maakte, maar feit dat het werkt is iig aanwezig nu!
Ik ben steen kapot, dus kruip er nu in en zal morgen zien wat er exact misging (en jouw post als oplossing aanwijzen), maar ik hou het nog even open tot ik er helemaal uit ben.

Tot zover iig super thx!!
Offline Thomas - 16/12/2013 23:15 (laatste wijziging 17/12/2013 09:27)
Avatar van Thomas Moderator Heeft dus wss niet zoveel te maken met utf-8, tis meer dat je die & escaped moet afdrukken om em op te slaan als &. Net zoals je die "¹" dus eigenlijk escaped afdrukt zodat die als "¹" wordt weergegeven. Je browser vertaalt dat dus al (&amp; naar &, &sup1; naar ¹). Als je &amp; submit dan wordt & doorgegeven, als je &sup1; submit, dan wordt ¹ doorgegeven en als je dus &amp;sup1; submit wordt dus &sup1; doorgegeven (en dat is wat je wilt).

Ongeacht de character set/encoding denk ik .
Offline vinTage - 17/12/2013 17:55
Avatar van vinTage Nieuw lid Nu heb ik iets nuttigs gedaan en dan hoef ik niet de & te escapen (dat vond ik al raar eigenlijk, want die & is gewoon een deel van de entitie &sup1;) Ook die accept charset in het form kan weg en je kan nu gewoon de entities in de select gebruiken en in de vergelijking.

En nu werkt het wel (al staat er nog altijd geen &sup1; in de db...??)

Enfin, de oplossing lijkt me toch iets te maken te hebben met de charset..
htmlentities($res['items_value'], ENT_QUOTES, "UTF-8");

De werkende versie:
  1. <?php
  2. mysql_connect ('**', '**', '**');
  3. mysql_select_db('test_facturen');
  4. //utf-8 meuk testzooi
  5. //mysql_query('SET NAMES utf8');
  6. if (!mysql_set_charset('utf8')) {
  7. echo "Error: Unable to set the character set.\n";
  8. }
  9. //echo mysql_client_encoding(); //utf8
  10.  
  11. if(isset($_POST['opslaan']))
  12. {
  13. $query = "insert into test_facturen (items_value)
  14. values ('".trim(mysql_real_escape_string($_POST['items']))."')";
  15. mysql_query($query)or die(mysql_error());
  16. header('location: ?aanpassen='.mysql_insert_id());
  17. }
  18. ?>
  19. <!DOCTYPE html>
  20. <html lang="nl">
  21. <head>
  22. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  23. <title>test</title>
  24. </head>
  25. <body>
  26. <?php
  27. $item_eenheid = '';
  28. if(isset($_GET['aanpassen']))
  29. {
  30. $qry = mysql_query("select items_value from test_facturen where id = ".mysql_real_escape_string($_GET['aanpassen']))or die(mysql_error());
  31. while($res = mysql_fetch_assoc($qry))
  32. {
  33. $item_eenheid = htmlentities($res['items_value'], ENT_QUOTES, "UTF-8");
  34. }
  35. }
  36. ?>
  37. <form action="" method="post">
  38. <select name="items">
  39. <option value="">eenheid</option>
  40. <option value="m&sup1;"<?php if($item_eenheid == 'm&sup1;'){ echo ' selected="selected"';}?>>m&sup1;</option>
  41. <option value="m&sup2;"<?php if($item_eenheid == 'm&sup2;') {echo ' selected="selected"';}?>>m&sup2;</option>
  42. <option value="V&amp;D"<?php if($item_eenheid == 'V&amp;D'){echo ' selected="selected"';}?>>V&D</option>
  43. </select>
  44. <input name="opslaan" type="submit" value="opslaan">
  45. </form>
  46. </body>
  47. </html>


Offline Thomas - 18/12/2013 15:01
Avatar van Thomas Moderator Heb even PHP.net er op nageslagen. Als je htmlentities() gebruikt hangt het van je PHP-versie af welke encoding als default wordt gebruikt.

< 5.4.0 is dit ISO-8859-1
>= 5.4.0 is dit UTF-8

Als de rest van je pagina UTF-8 is is het wel verstanding om expliciet UTF-8 te gebruiken, anders heb je mogelijk twee verschillende encodings op één pagina.

Die ENT_QUOTES doet er in dit geval niet toe, omdat je input geen (enkele of dubbele) quotes bevat.

In principe hebben we nu twee verschillende oplossingen die werken. Er is echter wel een verschil. In mijn oplossing sla je de waarde op in karakters waarbij karakters die "HTML character entity equivalents" hebben (denk aan speciale karakters) vertaald worden opgeslagen (in de vorm "&xxx;").
Normaal wordt "&xxx;" bij het afbeelden op een webpagina vertaald naar het symbool wat bij deze entiteit hoort. Door de & te schrijven als &amp; ontneem je de speciale betekenis van een speciale karakterreeks die start met &. "&amp;sup1;" wordt letterlijk afgebeeld als "&sup1;".

In jouw variant sla je het karakter "rauw" op, omdat je "&sup1;" niet escaped. Deze entiteit wordt dus als symbool afgedrukt en ook verstuurd.
htmlentities('¹', ENT_QUOTES, 'UTF-8') levert "&sup1;" (unescaped). Dit is de reden dat jouw variant werkt: de vergelijking gaat goed in de select, en het wordt als "¹" opgeslagen in de database.

Encoding is een soort van encryptie van uiteindelijke tekst. Neemt niet weg dat als je onbewust verschillende encodings door elkaar gebruikt het lastiger wordt om te achterhalen wat er nu eigenlijk aan de hand is. Maar het oorspronkelijke probleem heeft te maken met het gebruik van speciale tekens en hun equivalente HTML-entiteit, en hoe je hier mee omgaat. Encoding staat hier in principe los van. Als alles (pagina + database) ISO-8859-1 was geweest had je namelijk (met jouw oorspronkelijke opzet) hetzelfde probleem gehad.
Bedankt door: vinTage
Offline vinTage - 18/12/2013 20:56 (laatste wijziging 18/12/2013 22:04)
Avatar van vinTage Nieuw lid Ik ben er toch nog niet helemaal uit 
Okay, het werkt nu wel, maar ik heb liever letterlijk de waardes in de db die zijn ingegeven, en niet wat ook anders geïnterpreteerd kan worden (dus m&sup1; ipv m¹)
Het lijkt er nu dus even op dat het helemaal met geen van alles te maken heeft ?  

Alles is utf-8 (zover ik weet)
Dus al mijn rijen in de db waar je varchar oid kan invoeren, staan op utf_unicode_ci, zo ook de collatie van de db.
Via een php regeltje, zeg ik nog eens dat het over utf-8 gaat
  1. if (!mysql_set_charset('utf8')) {
  2. echo "Error: Unable to set the character set.\n";
  3. }

In de html zeg ik ook nog eens utf-8
  1. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">


Tot nu toe had ik het alleen over die select, maar als ik nu een andere input erbij pak (type="text" bv), en ik typ zelf &sup1; daarin, dan komt er in de db &sup1; te staan...Maar die select, waarin de geposte value toch echt &sup1; is, plaatst m¹ in de database.

Dit is nu iig in mijn werkversie, ik ga kijken of het ook zo is bij een simpele testversie en post die code dan wel (tenzij ik op de oorzaak uitkom )


EDIT:
Hmmmm.....nu lijkt het hele probleem imo op een raar iets wat de select veroorzaakt???
Met de volgende dump (zie dat alles op utf8 staat) en de volgende code (ook alles utf8?) en je ziet dat de select niet de value post, maar een 'bijhorende' variant, maar de textinput niet??

  1. CREATE TABLE `test_facturen` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `items_value` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  4. `items_msg` varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  5. PRIMARY KEY (`id`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

  1. <?php
  2. mysql_connect ('localhost', 'root', '**');
  3. //utf-8 meuk testzooi
  4. //mysql_query('SET NAMES utf8');
  5. if (!mysql_set_charset('utf8')) {
  6. echo "Error: Unable to set the character set.\n";
  7. }
  8. //echo mysql_client_encoding(); //utf8
  9.  
  10. if(isset($_POST['opslaan']))
  11. {
  12. $query = "insert into test_facturen (items_value, items_msg)
  13. values (
  14. '".trim(mysql_real_escape_string($_POST['items']))."',
  15. '".trim(mysql_real_escape_string($_POST['items_msg']))."'
  16. )";
  17. mysql_query($query)or die(mysql_error());
  18. header('location: ?aanpassen='.mysql_insert_id());
  19. }
  20. ?>
  21. <!DOCTYPE html>
  22. <html lang="nl">
  23. <head>
  24. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  25. <title>test</title>
  26. <style>
  27. xmp {display: block; border:1px solid red}
  28. </style>
  29. </head>
  30. <body>
  31. <?php
  32. $item_eenheid = '';
  33. $item_msg = '';
  34. if(isset($_GET['aanpassen']))
  35. {
  36. $qry = mysql_query("select * from test_facturen where id = ".mysql_real_escape_string($_GET['aanpassen']))or die(mysql_error());
  37. while($res = mysql_fetch_assoc($qry))
  38. {
  39. $item_eenheid = stripslashes(htmlentities($res['items_value'], ENT_QUOTES, "UTF-8"));
  40. $item_msg = stripslashes(htmlentities($res['items_msg'], ENT_QUOTES, "UTF-8"));
  41.  
  42. //toon de meuk zoals hij in de db staat...
  43. ?>
  44. waarde van items_value in de db: <xmp style="display:inline"><?= $res['items_value']?></xmp>
  45. <br>
  46. waarde van items_msg in de db: <xmp style="display:inline"><?= $res['items_msg']?></xmp>
  47. <?php
  48. }
  49. }
  50. ?>
  51.  
  52. <form action="" method="post">
  53. <select name="items">
  54. <option value="">eenheid</option>
  55. <option value="m&sup1;"<?php if($item_eenheid == 'm&sup1;'){ echo ' selected="selected"';}?>>m&sup1;</option>
  56. <option value="m&sup2;"<?php if($item_eenheid == 'm&sup2;') {echo ' selected="selected"';}?>>m&sup2;</option>
  57. <option value="V&amp;D"<?php if($item_eenheid == 'V&amp;D'){echo ' selected="selected"';}?>>V&D</option>
  58. </select>
  59. <br />
  60. <input name="items_msg" type="text" value="<?php echo $item_msg;?>" />
  61. <br />
  62. <input name="opslaan" type="submit" value="opslaan">
  63. </form>
  64. </body>
  65. </html>
Offline Thomas - 18/12/2013 21:54
Avatar van Thomas Moderator
vinTage schreef:
Tot nu toe had ik het alleen over die select, maar als ik nu een andere input erbij pak (type="text" bv), en ik typ zelf &sup1; daarin, dan komt er in de db &sup1; te staan...Maar die select, waarin de geposte value toch echt &sup1; is, plaatst m¹ in de database.


dropdown = html
textarea = tekst, daar heeft HTML geen betekenis, en wordt dus ook niet (automagisch op de achtergrond) geescaped of vertaald van entiteit naar symbool

als je in notepad een HTML-bestand opent zie je toch ook niet ineens paragrafen en headings enzo? 

Op dezelfde wijze: je kunt een tekst in een input-field met hierin een dubbele quote zonder problemen toevoegen, echter, als je deze wilt wijzigen, zul je die toch echt moeten escapen, anders breek je je html (je value="...iets met dubbele quotes..." loopt in de soep).

Dat is het verschil... min of meer .
Offline vinTage - 18/12/2013 22:10 (laatste wijziging 18/12/2013 22:14)
Avatar van vinTage Nieuw lid oh, je post gemist, was al een uur aan het editten.. (testen hier voor ik iets doms zei )

Maar neem eens een kijkje naar mijn (post hierboven) script als je wilt, daar staan de values van de select toch echt als 'html' en geen quotes oid...
Alle waardes gepost via die select, worden omgezet naar hun 'leesbare' variant dat zou toch niet mogen? dat moet gewoon de value zijn van de option en niet wat ik weergeef in de option..

of zeg ik nu stiekum toch iets doms ?  


EDIT
Het gaat me ondertussen eigenlijk meer over het feit dat mijn select

in de db plaats, terwijl er eigenlijk
m&sup1;
moet staan

(verder werkt die vergelijking uit de startpost goed op zowel jouw manier (escape de &) en mijn manier (die gebruik ik nu) door de charset in htmlentities te definieren.
Offline Thomas - 18/12/2013 22:35
Avatar van Thomas Moderator
vinTage schreef:
(verder werkt die vergelijking uit de startpost goed op zowel jouw manier (escape de &) en mijn manier (die gebruik ik nu) door de charset in htmlentities te definieren.


Dat is een extra stap die je moet nemen als je het op die manier oplost, omdat htmlentities anders de verkeerde encoding gebruikt om de boel te escapen en dan loopt $item_eenheid in de soep, tenzij je PHP versie nieuw genoeg is.

Ik denk dat je het zo moet zien:
&xxx; wordt behandeld als HTML, en wordt dus vertaald naar zijn equivalente symbool, bij afdrukken, bij opslaan, et cetera.

&amp;xxx; wordt behandeld als TEXT, maar, &amp; heeft betekenis in HTML, en wordt dus vertaald naar zijn equivalente symbool, te weten simpelweg "&". Oftewel het resultaat van het afdrukken van &amp;xxx; in HTML is &xxx; (wordt weergegeven op je scherm).

Als je vrolijk aan het typen bent in een inputveld of textarea, dan werk je in een TEXT-scope, je <b>-tags worden niet automatisch vertaald naar dikgedrukte tekst.

Misschien leg ik het verkeerd uit. Alles wat je afdrukt moet je escapen, tenzij je wilt dat dit zijn speciale HTML-betekenis behoudt.

Dit doet mij denken aan een sketch .
Offline vinTage - 18/12/2013 22:53 (laatste wijziging 18/12/2013 23:01)
Avatar van vinTage Nieuw lid Het zal wel aan mij liggen, maar ik weet dat &amp; in html als & wordt weergegeven, en m&sup1; wordt als m¹ weergegeven (m en aaneengesloten &sup1;)
Ook weet ik het verschil wel tussen geparste html of de textuele inhoud ervan.

Maar de value van option in de select is toch echt m&sup1;

Mijns inziens moet mijn formulier de value posten naar de db, en niet het equivalente symbool..!?

----------------
offtopic, de reden dat ik hier een 'probleem' (een probleem is het niet meer omdat de vergelijking werkt) van maak, is omdat ik gewoon duidelijke vergelijkingen wil kunnen maken met waardes uit de db en dat het leesbaar is in de db (zelfs al post men daar de meest gare characters) en er NERGENS (niet in db/htmlsource/code/etc) van die rare varianten te zien zijn zoals bijvoorbeeld zwarte ruitjes met een ? erin, of Ãonbeduidendemeuk...Zover goed op weg, alleen post de select die equivalent ipv de value  

Citaat:
Dat is een extra stap die je moet nemen als je het op die manier oplost, omdat htmlentities anders de verkeerde encoding gebruikt om de boel te escapen en dan loopt $item_eenheid in de soep, tenzij je PHP versie nieuw genoeg is.

Ik wil juist GEEN extra stap. Daarom geef ik via 'alles' aan dat het om utf-8 gaat.
Alle waardes worden 'as is' opgeslagen (door mysql_real_escape_string)
Het uitlezen doe ik normaliter door htmlenties, omdat degene die dit prog gaat gebruiken misschien wel 'domme' text invoert...hij gelooft gerust dat iemand '<marquee>' heet en zijn adres 'droptable' is

Als de db nou gewoon de geposte value van de option op zou slaan, was er geen probleem 
Offline Thomas - 18/12/2013 23:23
Avatar van Thomas Moderator Vergelijk het hiermee:

<input type="text" value="dit is invoer met een dubbele quote " oh woops" />
<textarea><b>dit snijdt geen hout</b> maar werkt wel, mogelijk omdat je browser denkt slim te zijn...
<script>alert('hoi')</script></textarea>

Dat moet ook geescaped worden, ook uit security overwegingen enzo. (voeg een </textarea> toe als invoer hoho). Het probleem ontstaat ook pas wanneer je eerder ingevulde tekst weer opnieuw in je HTML stopt. Deze tekst kan best een speciale betekenis in HTML hebben, ook al was het oorspronkelijk als tekst gesubmit.

Alles wat niet geescaped wordt (ontdaan wordt van zijn speciale betekenis in HTML) wordt automatisch geinterpreteerd als HTML. Hoe moet een browser anders uitvogelen of er nou HTML bedoeld wordt of een "plaintext" variant van die HTML? Toch alleen als je het zelf aangeeft (&amp; in plaats van &).
Offline vinTage - 18/12/2013 23:39 (laatste wijziging 18/12/2013 23:53)
Avatar van vinTage Nieuw lid Ik waardeer echt je input wel hoor, maar ik denk tevens dat je me een beetje onderschat  

Alle inputs worden opgeslagen dmv mysql_real_escape_string -> geen gefuck met de db dmv 'domme' input.
Uitlezen gebeurd door htmlentities -> niemand kan dmv js (oid) aan gevoelige info komen.

Op momenten waarbij ik denk dat een string uit de database geen kwaad kan, plaats ik die string 'as is' in een input.



WAAROM post mijn formulier onderdeel (select) niet de waarde die ik wil dat hij geeft...waar is die value anders voor bedoeld?

Hoe ik verder omga met de waardes in de de db is mijn probleem, maar er moet wel in komen te staan wat ik wil, en dat gebeurd niet...bewijs is te vinden in dit scriptje.



edit: we lopen een uur achter?
Offline Thomas - 18/12/2013 23:53
Avatar van Thomas Moderator
vinTage schreef:
Ik waardeer echt je input wel hoor, maar ik denk tevens dat je me een beetje onderschat

<3

vinTage schreef:
Alle inputs worden opgeslagen dmv mysql_real_escape_string -> geen gefuck met de db dmv 'domme' input.

Hold on, dat dient een ander doel, het escaped speciale SQL karakters, oa om SQL injection tegen te gaan.

vinTage schreef:
Uitlezen gebeurd door htmlentities -> niemand kan dmv js (oid) aan gevoelige info komen.

Sounds good.

vinTage schreef:
Op momenten waarbij ik denk dat een string uit de database geen kwaad kan, plaats ik die string 'as is' in een input.

Be paranoid! (no serious!) Geen enkele input is te vertrouwen, ook je eigen niet. Het is tevens ook veel makkelijker: je hoeft niet elke keer de afweging te maken of er op terug te komen (wel, niet, misschien toch wel escapen? mehhhhhh).
Filter input, escape output.
Altijd.

vinTage schreef:
WAAROM post mijn formulier onderdeel (select) niet de waarde die ik wil dat hij geeft...waar is die value anders voor bedoeld?

Omdat, hoe graag je ook wilt dat die value als plaintext behandeld wordt, het nog steeds HTML is .

vinTage schreef:
Hoe ik verder omga met de waardes in de de db is mijn probleem

Fair enough, maar ik had al aangegeven dat dit (wat character encoding betreft) voor je probleem niet uitmaakt .

vinTage schreef:
maar er moet wel in komen te staan wat ik wil, en dat gebeurd niet...bewijs is te vinden in dit scriptje.

Ik zie geen andere oplossing dan het escapen van de option values, als je het als html entity wilt (&sup; and all that jazz) opslaan. Sorry 
Offline vinTage - 19/12/2013 00:03
Avatar van vinTage Nieuw lid Nuja, ik weet niet hoe ik het verder nog moet/kan uitleggen.

Bedankt voor het meedenken!
Maar de uiteindelijke oplossing(ook al begon mijn vraag verkeerd en ben ik pas nadien op een werkelijke vraag uitgekomen) vind ik dat er nog niet gegeven is.
Ik zou eventueel wel per quote ook een weerwoord willen geven, maar dat is alemaal irrelevant als je mijn code blokjes GOED bekijkt (de test versies heb ik gematigd omdat die niet live gaan)..

Citaat:
vinTage schreef:
maar er moet wel in komen te staan wat ik wil, en dat gebeurd niet...bewijs is te vinden in dit scriptje.

Ik zie geen andere oplossing dan het escapen van de option values, als je het als html entity wilt (&sup; and all that jazz) opslaan. Sorry

Jep, daar lijkt het misschien wel op, maar ik 'voel' dat het wel (beter/anders/as is) kan!

Een option value is imo geen html maar een string.

Citaat:
Be paranoid! (no serious!)
daarom htmlentities he?
Offline Thomas - 19/12/2013 00:23 (laatste wijziging 19/12/2013 00:26)
Avatar van Thomas Moderator Op zich heb je wel een punt. Volgens de XHTML 1.0 spec is een option value CDATA. Dus wat is het probleem inderdaad .

Maar je kunt ook heel simpel redeneren: je werkt in een X(HT)ML document. Daarin moeten de volgende 5 karakters (EDIT: waar dan ook!) geescaped worden:
" &quot;
' &apos;
< &lt;
> &gt;
& &amp;

Ik bedoel het volgende niet beledigend, maar in die zin "klopt" je HTML dus eigenlijk niet.

Het heeft geen zin een situatie te bestuderen waarvan je weet dat die niet klopt. Repareer eerst de foutieve situatie, en kijk vervolgens of het ongewenste gedrag nog steeds optreedt.

Ik denk dat we hier allebei een beetje te lang naar het staren zijn, maar probeer het voorgaande even te laten bezinken .
Offline vinTage - 20/12/2013 00:13
Avatar van vinTage Nieuw lid Ik zou niet weten wat er fout is aan de html?
Zelfs de voorbeeldjes zijn valid html5.

Feit is gewoon dat als ik in een textfield &sup1; typ en naar de database stuur, dat ik dan in de database letterlijk &sup1; te lezen is.
Terwijl als ik &sup1; als value van een option verstuur naar de database, dat er dan (tot nu onverklaarbare reden) ¹ te lezen is.

Ik denk nog altijd dat het (misschien heel ergens in de verte) toch stiekem nog iets met de charset te maken heeft, maar ik ga door met frutten tot ik het gevonden heb en ik zonder omwegen gewoon kan gebruiken wat ik wil 
Offline Thomas - 20/12/2013 00:31
Avatar van Thomas Moderator &sup1; en ¹ zijn in HTML equivalent.

Als je een tekst wilt afdrukken met hierin een & (ampersand) die verder geen speciale betekenis heeft (het is slechts tekst) dan moet je deze escapen.

Denk aan: <p>Henk &amp; Piet</p>, <a href="test.php?a=1&amp;b=2">lala</a> etc.

That's all there is to it.

vinTage schreef:
Feit is gewoon dat als ik in een textfield &sup1; typ en naar de database stuur, dat ik dan in de database letterlijk &sup1; te lezen is.


Dat komt nog steeds omdat je tekst aan het typen bent, en geen HTML. In (plain)tekst zijn &sup1; en ¹ niet equivalent (in de zin dat er hetzelfde wordt afgedrukt). Als je tekst verstuurd wordt deze ook niet "vertaald" naar iets anders. Tekst is tekst (ongeacht de charset). Als de charsets tussen bron en bestemming verschillen, dan gaan er zaken mis, maar anders niet.

De charset maakt het verhaal wat ingewikkelder (er kan meer misgaan) maar er is in dit geval geen causaal verband tussen het probleem waar je mee worstelt en de (gebruikte) charset(s).

Zoals ik al eerder voorstelde, maak alles ISOxyz, je probleem blijft. Dat zou toch min of meer bewijzen dat de charset niet aan de oorsprong van je probleem ligt?
Offline vinTage - 20/12/2013 01:10 (laatste wijziging 20/12/2013 11:36)
Avatar van vinTage Nieuw lid
FangorN schreef:
¹ en ¹ zijn in HTML equivalent.

Wel grappig, want ik quote jouw bericht en ipv &sup1; staat er een ¹ in de textarea  

FangorN schreef:
Zoals ik al eerder voorstelde, maak alles ISOxyz, je probleem blijft. Dat zou toch min of meer bewijzen dat de charset niet aan de oorsprong van je probleem ligt?

Ik heb nu een 'gare' versie gemaakt (dus geen utf-8 in de meta tag en voor de db, en lollig, maar nu komt er m¹ in de database te staan ipv ¹ 

Nuja, ik blijf toch lekker doorzoeken, want mijn buik zegt nog altijd <s>ik heb dorst</s>, de value zou gewoon een string moeten zijn...alhoewel er steeds meer twijfel onstaat 

edit: in die gare testversie maakt wel of geen meta tag ook een verschil, dus dit smijt ik gewoon weg en ga verder met mijn bestaande test versie.
Daar heb ik trouwens ook weer geleerd dat ontdanks alle 'aanroepen' van utf-8 nog niet perse wil zeggen dat alles utf-8 is.., voor mij nieuw dus 

als ik dit echo mb_internal_encoding(); dan kwam er isoiets te staan, maar nu utf8, dankzij mb_internal_encoding("UTF-8");
Zo ook de mb_detect_order order aangepast, want eerste value was ascii ipv utf8

edit2: mss nutteloze update, maar html5 versus xhtml strict maakt ook geen verschil

edit3:
Eens bekeken wat de definitie van cdata voor een option dan is, en blijkbaar is dat dus niet 'letterlijk' een string, maar mag/zal geïnterpreteerd worden naar bijhorende entiteiten?
Begrijp ik dat dan goed?
Citaat:
CDATA is a sequence of characters from the document character set and may include character entities. User agents should interpret attribute values as follows:

Replace character entities with characters,

Ignore line feeds,
Replace each carriage return or tab with a single space.

User agents may ignore leading and trailing white space in CDATA attribute values (e.g., " myval " may be interpreted as "myval"). Authors should not declare attribute values with leading or trailing white space.



Nou, dan vind ik het value attribuut maar een slecht doordacht ding als ik er niet eens in kan plaatsen wat ik wil!
Met wat ongelukkige ouders die je &sup1; genoemd hebben, en je kunt nooit geselecteerd worden 
Gesponsorde links
Je moet ingelogd zijn om een reactie te kunnen posten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.319s