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¹
m² ipv m²
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¹ en m² 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?!
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?
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.
//utf-8 meuk testzooi
mysql_query('SET NAMES utf8');
if (!mysql_set_charset('utf8')) {
echo "Error: Unable to set the character set.\n";
exit;
}
echo mysql_client_encoding(); //geeft echt utf8
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?
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:
Als er dus "m¹" in je database staat (wat ik eigenlijk gewoon verwacht), en je gooit hier htmlentities overheen wordt dit "m¹"?
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 &, 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?
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
edit2: het is dus dat er GEEN m¹ in de db terecht komt, DAT is mijn probleem
Thomas - 16/12/2013 22:36 (laatste wijziging 16/12/2013 22:39)
Moderator
escape de values, oftewel
<option value="m&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 &
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
Thomas - 16/12/2013 22:56 (laatste wijziging 16/12/2013 23:00)
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!!
Thomas - 16/12/2013 23:15 (laatste wijziging 17/12/2013 09:27)
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 (& naar &, ¹ naar ¹). Als je & submit dan wordt & doorgegeven, als je ¹ submit, dan wordt ¹ doorgegeven en als je dus &sup1; submit wordt dus ¹ doorgegeven (en dat is wat je wilt).
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 ¹) 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 ¹ 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");
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 & ontneem je de speciale betekenis van een speciale karakterreeks die start met &. "&sup1;" wordt letterlijk afgebeeld als "¹".
In jouw variant sla je het karakter "rauw" op, omdat je "¹" niet escaped. Deze entiteit wordt dus als symbool afgedrukt en ook verstuurd.
htmlentities('¹', ENT_QUOTES, 'UTF-8') levert "¹" (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.
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¹ 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
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 ¹ daarin, dan komt er in de db ¹ te staan...Maar die select, waarin de geposte value toch echt ¹ 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??
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 ¹ daarin, dan komt er in de db ¹ te staan...Maar die select, waarin de geposte value toch echt ¹ 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).
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
m¹
in de db plaats, terwijl er eigenlijk
m¹
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.
(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.
&xxx; wordt behandeld als TEXT, maar, & heeft betekenis in HTML, en wordt dus vertaald naar zijn equivalente symbool, te weten simpelweg "&". Oftewel het resultaat van het afdrukken van &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.
Het zal wel aan mij liggen, maar ik weet dat & in html als & wordt weergegeven, en m¹ wordt als m¹ weergegeven (m en aaneengesloten ¹)
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¹
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
<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 (& in plaats van &).
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.
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 (⊃ and all that jazz) opslaan. Sorry
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 (⊃ 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?
Thomas - 19/12/2013 00:23 (laatste wijziging 19/12/2013 00:26)
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:
" "
' '
< <
> >
& &
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 .
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 ¹ typ en naar de database stuur, dat ik dan in de database letterlijk ¹ te lezen is.
Terwijl als ik ¹ 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
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 & Piet</p>, <a href="test.php?a=1&b=2">lala</a> etc.
That's all there is to it.
vinTage schreef:
Feit is gewoon dat als ik in een textfield ¹ typ en naar de database stuur, dat ik dan in de database letterlijk ¹ te lezen is.
Dat komt nog steeds omdat je tekst aan het typen bent, en geen HTML. In (plain)tekst zijn ¹ 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?
Wel grappig, want ik quote jouw bericht en ipv ¹ 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 ¹ genoemd hebben, en je kunt nooit geselecteerd worden
Gesponsorde links
Je moet ingelogd zijn om een reactie te kunnen posten.