login  Naam:   Wachtwoord: 
Registreer je!
 Forum

Htmlentities werkt niet in combinatie met mijn MySQL database! (Opgelost)

Offline Martijn2008 - 05/03/2009 20:21
Avatar van Martijn2008PHP beginner Hallo allemaal,

Mijn website moet volledig (X)HTML 1.0 strict zijn. Met dat idee in mijn achterhoofd heb ik vanmiddag de chatbox van Sima gejoined. Daar stelde ik met volle moed mijn vraag, hoe zet ik het woord `` èèn `` om in een goede (X)HTML code. Kort daarna kreeg ik al een reactie, de php functie htmlentities zou uitkomst moeten bieden. Dus ik testen, als resultaat kreeg ik één. Dat is dus zeker niet goed.

Voor mijn website maak ik gebruik van een MySQL database. Op deze database heb ik volledige schrijf / lees en bewerk rechten. Al snel was mijn database onderwerp van gesprek. Er werd gerefereerd naar het volgende artikel. Helaas moet ik zeggen dat ik dat artikel niet helemaal kan volgen. Vandaar dat ik jullie wil vragen even te kijken naar mijn lees en schrijf functie. Hopelijk zien jullie de oplossing wel.

  1. <?
  2.  
  3. function write($string)
  4. {
  5. $string = mysql_real_escape_string($string);
  6. $string = htmlspecialchars($string);
  7. return $string;
  8. }
  9.  
  10. function read($entry)
  11. {
  12. $string = stripslashes($string);
  13. $string = htmlspecialchars_decode($string);
  14. $string = strip_tags($string);
  15. $string = htmlspecialchars($string);
  16. $string = htmlentities($string);
  17. return $string;
  18. }
  19.  
  20. ?>


Hartstikke bedankt alvast!

Martijn

20 antwoorden

Gesponsorde links
Offline nick5556 - 05/03/2009 20:24
Avatar van nick5556 PHP beginner Volgensmij bestaat er zowieso geen htmlspecialchars_decode of zie ik dit verkeerd?

PS: Ik heb zo gauw even geen antwoord op je vraag 
Offline Martijn - 05/03/2009 20:37
Avatar van Martijn Crew PHP special chars moet niet bij je write. Als write naar je db is
Offline Martijn2008 - 05/03/2009 20:41
Avatar van Martijn2008 PHP beginner Ik heb daarnet htmlspecialchars verwijderd uit de write action naar de DB, maar het probleem is daarmee nog niet opgelost.
Offline Wim - 05/03/2009 22:02 (laatste wijziging 05/03/2009 22:04)
Avatar van Wim Crew algemeen
http://www.php.net/htmlentities schreef:
This function is identical to htmlspecialchars() in all ways, except with htmlentities(), all characters which have HTML character entity equivalents are translated into these entities.

If you're wanting to decode instead (the reverse) you can use html_entity_decode().


Waarom ga je het ook eerst decoden om nadien weer te encoden? Dan vraag je toch om problemen? niet?

//edit:
irc schreef:
<Martijn> Als ik die functie apart neem, dus gewoon los, zonder DB connection, en ik geef als input één dan doet die functie gewoon goed zijn werk. En dat terwijl de DB dezelfde input geeft. Ontzettend vaag verhaal dus, maar het is toch echt zo.


Kan je iets meer code geven dan? (heb dit hier zo even bijgezet zodat de rest het probleem ook wat beter kan begrijpen)
Offline Martijn2008 - 05/03/2009 22:36
Avatar van Martijn2008 PHP beginner Meer code? Welke code zou je graag willen zien? Ik bedoel, ik gebruik bovenstaande functies om de input weg te schrijven en vervolgens later weer op te halen? Stel dat ik het woord '' één " met de functie write naar mijn DB weg schrijf. En ik haal dat later op met de read functie, dan is dit de output " één ".
Offline vinTage - 05/03/2009 22:38
Avatar van vinTage Nieuw lid Geef db en css en charset eens allemaal utf-8 mee.
Offline Martijn2008 - 05/03/2009 22:43 (laatste wijziging 05/03/2009 22:44)
Avatar van Martijn2008 PHP beginner Sorry, maar ik begrijp niet precies wat je bedoeld. Is dat een php functie? Wat heeft mijn CSS met de php functie htmlentities te maken?
Offline vinTage - 05/03/2009 22:44
Avatar van vinTage Nieuw lid Das geen php, dat is gewoon html (en mysql)
Offline Martijn2008 - 05/03/2009 22:46
Avatar van Martijn2008 PHP beginner Hoe stel ik mijn MySQL database dan op UTF-8 in? Kan ik dat bijvoorbeeld doen met phpMyAdmin?
Offline Koen - 05/03/2009 23:06
Avatar van Koen PHP expert SQL:
  1. ALTER TABLE `tabel` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

HTML:
  1. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />


Dacht ik 
Offline Martijn2008 - 05/03/2009 23:08 (laatste wijziging 06/03/2009 15:26)
Avatar van Martijn2008 PHP beginner Is het soms de bedoeling dat ik iedere tabel apart omzet naar UTF-8 of kan ik mijn hele database ook in 1 keer omzetten?

In phpMyAdmin vond ik: " utf8_unicode_ci ", moet ik deze soms hebben?

UPDATE: Database type inmiddels geswitched naar UTF-8, jammer genoeg zonder succes.

UPDATE2: Het probleem bevindt zich in de broncode. FireFox weergeeft de website gewoon goed! Het probleem moet dus server side gezocht worden.

  1. // html-sourcecode
  2.  
  3. èèn<br />


UPDATE3: Het zit hem waarschijnlijk in het plaatsen van de data in de database en het lezen. De functie htmlentities werkt wel gewoon stand-alone. Een foutieve server-configuratie lijkt mij daarom bijna onmogelijk.

  1. <?
  2.  
  3. echo htmlentities("èèn");
  4. // output: &egrave;&egrave;n -> èèn -> de functie werkt dus :)
  5.  
  6. ?>


UPDATE4: Ik htmlentities in de write functie geplaatst. Ook dit lost het probleem niet op. Output op deze manier is:

  1. èèn


UPDATE5: Htmlentities in de write functie is ook niet zo'n succes. Daarom heb ik de htmlentities toch maar weer terug geplaatst in de read functie. Helaas nogsteeds niet met het gewenste resultaat.

  1. // html sourcecode
  2.  
  3. één<br />


UPDATE6: Ik heb de volgende code getest:

  1. <?
  2.  
  3. $q = "SELECT * FROM gastenboek WHERE uid='" . intval($_GET['uid']) . "'";
  4. $r = mysql_query($q) or die (mysql_error());
  5. $c = mysql_num_rows($r);
  6. if($c==0)
  7. {
  8. echo 'Geen berichten';
  9. }
  10. else
  11. {
  12. while($sql = mysql_fetch_assoc($r))
  13. {
  14. $strGb = $sql['bericht'];
  15. // $strGb heeft hier de volgende waarde: èèn
  16.  
  17. $strGb = htmlentities($strGb);
  18. echo $strGb;
  19. }
  20. }
  21.  
  22. // output: &Atilde;&uml;&Atilde;&uml;
  23.  
  24. ?>


UPDATE7: Bij de invoer maak ik nu alleen nog gebruik van mysql_real_escape_string en bij de uitvoer van htmlentities. Ook dit brengt niet de oplossing.
Offline Wim - 06/03/2009 15:37
Avatar van Wim Crew algemeen Heb je het nu al eens op een andere server geprobeerd zoals ik je gisteren adviseerde? Zo kan je uitsluiten dat het aan je webserver/database server ligt, of zo kan je erachter komen dat het probleem zich daar bevindt...

Een xampp/usbwebserver/... volstaat hier voor (en die hebben als voordeel dat je ze enkel moet extracten & runnen )

Kan je ook eens een dump van je db geven?
Offline Martijn2008 - 06/03/2009 16:00
Avatar van Martijn2008 PHP beginner Het heeft niets met mijn DB te maken ben ik al achter. Ik heb de volgende code gebruikt om dat te testen. Als input in de textarea gaf ik weer het woord èèn, als output kreeg ik èèn.

  1. <?php
  2.  
  3. if(empty($_POST['bericht']))
  4. {
  5. echo '<form method="post" action="">
  6. <textarea name="bericht"></textarea>
  7. <input type="submit" name="submit" value="submit" />
  8. </form>';
  9. }
  10. else
  11. {
  12. echo htmlentities($_POST['bericht']);
  13. }
  14.  
  15. // output: èèn
  16.  
  17. ?>
Offline Richard - 06/03/2009 16:51 (laatste wijziging 06/03/2009 16:52)
Avatar van Richard Crew algemeen Ja, dat is nogal logisch aangezien je geen charset of wat dan ook meegeeft..

Als je het allemaal goed wil hebben zal _ieder_ aspect van applicatie UTF8 moeten gebruiken:
- database (ook de verbinding: SET NAMES 'utf8')
- tekstbestanden
- output
Offline Martijn2008 - 06/03/2009 16:54 (laatste wijziging 06/03/2009 17:12)
Avatar van Martijn2008 PHP beginner @JeXuS Zou je jouw uitleg misschien wat kunnen toelichten ? Voorbeelden?
Offline Richard - 06/03/2009 17:23
Avatar van Richard Crew algemeen Zeker. :-) In neem even als voorbeeld UTF8.

Ten eerste, alle kolommen in al je tabellen stel je in op utf8. (MySQL: utf8_unicode_ci ofzo)
Als je nu verbinding maakt met de database, voer je direct de query "SET NAMES 'utf8'" uit, zo kan de verbinding er ook goed mee overweg.

Iedere pagina waarop je nu data laat zien of data laat invoeren, stuur je als header mee: header('Content-Type: text/html;charset=utf8');
Daarnaast stuur je een meta http-equiv mee:
<meta http-equiv="Content-Type" content="text/html;charset=utf8" />

In principe zou alleen de header genoeg moeten zijn, maar zo weet je het tenminste zeker. :-)

Nog meer dat je wil weten? ;)
Offline Martijn2008 - 06/03/2009 17:34
Avatar van Martijn2008 PHP beginner Ik heb het even geprobeerd met mijn test-scriptje. Helaas, maar toch is het waar, deze oplossing werkt ook niet. Tenzij ik natuurlijk iets niet helemaal goed doe.

  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  4. </head>
  5.  
  6. <body>
  7. <?
  8.  
  9. header('Content-Type: text/html;charset=utf8');
  10.  
  11. if(empty($_POST['bericht']))
  12. {
  13. echo "\n" . '<form method="post" action="">
  14. <textarea name="bericht"></textarea>
  15. <input type="submit" name="submit" value="submit" />
  16. </form>' . "\n";
  17. }
  18. else
  19. {
  20. echo htmlentities($_POST['bericht']);
  21. }
  22.  
  23. ?>
  24. </body>
  25. </html>
Offline Wim - 06/03/2009 17:39
Avatar van Wim Crew algemeen krijg je met dat script geen error??? (headers allready sent)

http://php.net/header schreef:
Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include(), or require(), functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file.
Offline Martijn2008 - 06/03/2009 17:48 (laatste wijziging 11/01/2015 19:04)
Avatar van Martijn2008 PHP beginner Ja, je hebt gelijk, had in mijn htaccess error onderdrukking ingeschakeld. Maar werkt nog niet.

UPDATE: Het probleem bevindt zich in de server configuratie. Apache2Triad runt mijn voorbeeld zonder problemen. Heeft iemand misschien een idee waar ik moet zoeken? php.ini, httpd.conf, apache2.conf?

OPLOSSING: utf8_decode na het uitlezen van de DB gebruiken.

mod edit: dit is waarschijnlijk niet de goede oplossing
Offline Thomas - 11/01/2015 19:01 (laatste wijziging 11/01/2015 19:03)
Avatar van Thomas Moderator Hiermee haal ik wellicht oude koeien uit de sloot, maar deze encoderingsproblemen zijn nog redelijk actueel.

Als je utf8_decode moet toepassen op data uit een utf8-tabel om deze af te drukken in een UTF-8 document, dan houdt dit waarschijnlijk in dat de gegevens in je database dubbel ge-encodeerd zijn. Dit werd waarschijnlijk weer veroorzaakt doordat je geen character set had geselecteerd op het moment van wegschrijven van je data.

MySQL is zelf redelijk intelligent als het gaat om omzettingen tussen verschillende encoderingen. Stel je hebt een utf8-tabel, maar je hebt geen character encoding meegegeven bij het maken van een verbinding met je database. Er is dan een grote kans dat deze de default character encoding pakt (latin1). Je brongegevens uit je formulier waren al UTF-8 door je header(), meta-tag en mogelijk accept-charset property in je form-tag. Maar MySQL is (nog steeds) in de veronderstelling dat data die naar je database wordt gestuurd latin1-data is. En MySQL ziet dat je dat in een utf8 database-tabel of -kolom probeert weg te schrijven. Dus zet MySQL deze data (nogmaals) om naar utf8. Je data staat dus vervolgens dubbel ge-encodeerd in je database.

Als je dan vervolgens je data weer probeert uit te lezen (zonder het instellen van een character set) dan ziet MySQL dat je bron-data (in je database) utf8 is, maar je connectie is / verwacht latin1. MySQL zal dan dus zelf al een utf8-decodering doen.

In de oorspronkelijke opzet zal dat dus (lijken te) werken, want je gaat dan weer terug van een dubbele encoding naar een enkele encoding. Alles lijkt dan goed te gaan... totdat je je connectie credentials repareert .

Repareer je echter je connectie door het instellen van de juiste te gebruiken character encoding door gebruikmaking van een _set_charset() functie, dan zal MySQL niets omzetten bij schrijven naar / lezen uit de database. MySQL is dan al verbonden met gebruikmaking van utf8-encodering, en de database-tabellen en -kolommen zijn ook utf8 - er hoeft dan simpelweg niets vertaald te worden.

Tot slot, als je speciale karakters wilt neutraliseren bij het afdrukken in een HTML-document, zodat deze geen speciale betekenis hebben in de HTML-context dan kun je hiervoor htmlentities() of (wellicht beter) htmlspecialchars() gebruiken. Hierbij moet je wel een character-encoding meegeven (derde parameter). Tot PHP-versie 5.4 wordt verondersteld dat dit ISO-8859-1 (min of meer equivalent met latin1 in MySQL) is. Het is beter om expliciet een character encoding mee te geven.

In dit topic is het probleem waarschijnlijk in eerste instantie dat de data in de database niet op de goede manier is weggeschreven. Als je allerlei (extra) goocheltruuks moet uithalen om e.e.a. fatsoenlijk af te drukken dan is er ergens iets mis. De eerste stap bij het oplossen van dit soort problemen lijkt mij het creëren van een kloppende uitgangssituatie. Dat wil zeggen: schakel ALLE character encoderingen gelijk:
- die van je HTML-document
- die van je database-connectie
- die van je database tabellen- en kolommen-structuur
- en als laatste (en wellicht belangrijkste), die van de encodering van je opgeslagen data

Het controleren van de character-encoding van opgeslagen data kan relatief eenvoudig. Aan de MySQL-zijde kun je data door de MySQL-functie HEX() halen. Aan de PHP-zijde kun je de data door de PHP-functie bin2hex() halen. Als de uitkomsten van deze twee functie-aanroepen op dezelfde brondata verschillend zijn betekent dit dat er ergens vertalingen (tussen character encoderingen) hebben plaatsgevonden, waarschijnlijk doordat je bij het maken van een database-connectie geen (of de verkeerde) character encoding had geselecteerd.

Deze twee functies zou je ook kunnen gebruiken om te kijken of de weggeschreven data wel de juiste character encoding heeft, of dat de data zelf corrupt is, deze functies zijn namelijk niet character encoding aware, oftewel, geven altijd dezelfde "uitkomst" op dezelfde input ongeacht de op dat moment gebruikte character encoding (hetzij in de database, hetzij in je PHP-script).
Bedankt door: Abbas
Gesponsorde links
Je moet ingelogd zijn om een reactie te kunnen posten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.255s