UTF-8 karakter set probleem met externe data

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Erwin H

Erwin H

26/03/2013 17:38:31
Quote Anchor link
Problemen met rare tekens op mijn site had ik dacht ik al achter me gelaten, maar toch niet. Op zich gaat er niets mis met het tonen van tekens als een é. Alleen nu loop ik toch tegen een probleem aan.

Het probleem zit hem in de Google geocoding applicatie. Als ik daar gegevens van opvraag dan krijg ik een string terug die volgens de http header (en volgens de php encoding check) in UTF-8 formaat is. Als ik de string gewoon op naar het scherm print dan staat er ook gewoon wat ik moet zien: "Saint Barthélemy".
Echter, als ik deze string gebruik in een query om gegevens uit mijn database te halen dan krijg ik geen resultaten (terwijl er echt een record in staat met Saint Barthélemy als tekst). In mijn database staat alles op UTF-8 (unicode_ci), alleen toch is het anders dan wat ik van Google krijg. Als ik namelijk de HEX waardes bekijk dan krijg ik niet hetzelfde:
Saint Barthélemy in de database: 5361696E74204261727468266561637574653B6C656D79
Saint Barthélemy vanuit Google: 5361696E74204261727468E96C656D79

Dit zijn dus duidelijk twee verschillende strings en blijkbaar zal ik de waarde die ik van Google krijg moeten converteren.... maar hoe? Ik heb het geprobeerd via php (utf8_encode, utf8_decode, mb_convert_encoding) en via mysql (CONVERT('Saint Barthélemy' USING utf8)), maar tot dusverre heeft niets geholpen. Op de een of andere manier zijn en blijven die strings ongelijk aan elkaar. Iemand met ervaring of ideeen?
 
PHP hulp

PHP hulp

21/11/2024 21:03:05
 
Frank Nietbelangrijk

Frank Nietbelangrijk

26/03/2013 18:11:32
Quote Anchor link
doe je dit dan ook?:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
/* change character set to utf8 */
if (!mysqli_set_charset($link, "utf8")) {
    printf("Error loading character set utf8: %s\n", mysqli_error($link));
?>


het is het enigste dat ik kan bedenken.
 
Erwin H

Erwin H

26/03/2013 18:13:55
Quote Anchor link
Ik gebruik geen mysqli, maar PDO. Daar zet ik de characterset van de verbinding met de query:
"SET names utf8, COLLATION_CONNECTION='utf8_unicode_ci', CHARACTER SET utf8"

Toevoeging op 26/03/2013 19:03:59:

Ik heb de, of in elk geval een, oplossing gevonden. De precieze reden waarom het werkt ben ik zelf ook nog niet achter, dus als iemand alsnog meer info kan verschaffen dan heel graag. Of het dus ook echt voor alle situaties de oplossing is durf ik ook niet te zeggen.

Zoals gezegd was ik dus op zoek naar een manier om de string die ik van Google krijg te converteren naar eenzelfde formaat als de strings die in de database staan. In de database heb ik de collatie op utf8_unicode_ci staan en zoals het nu lijkt, kan ik de Google string converteren via htmlentities. In php dus.
Via deze conversie krijg ik eenzelfde string en werkt mijn query weer:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$value
= htmlentities( $value, 0, 'UTF-8' );
?>


Misschien toch eens wat dieper in karaketer sets en collaties gaan duiken, want dit heeft me veel te veel tijd gekost....
 
Erwin H

Erwin H

18/04/2013 10:54:30
Quote Anchor link
En dan denk je er uit te zijn, komt er toch weer iets boven drijven dat niet werkt.

Vandaag kwam ik langs strings die nog weer wat vreemdere tekens bevatten: ? ? ? ? ?
Deze worden dus niet met htmlentities gecodeerd, want zo blijkt, deze tekens hebben geen html code. Althans niet volgens deze lijst: http://ascii.cl/htmlcodes.htm
Ze zijn echter wel onderdeel van de UTF-8 unicode lijst en zouden dus wel in de database moeten kunnen worden opgenomen. Vraag is: hoe?

Op dit moment jaag ik de string door htmlentities waarna het grootste deel van de vreemde tekens goed wordt geconverteerd. Bovenstaande (plus nog een paar) blijven echter ongeconverteerd en worden bij een insert in de database dus een onleesbaar teken. Op het scherm komen ze als vraagtekens. Welke conversie kan ik uitvoeren om het dus wel juist in de database te krijgen?

Toevoeging op 18/04/2013 10:56:59:

En ik zie dat de tekens hier ook niet worden gelezen....

Meer info:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
U+011B    ?    c4 9b    LATIN SMALL LETTER E WITH CARON
U+0131    ?    c4 b1    LATIN SMALL LETTER DOTLESS I
U+0151    ?    c5 91    LATIN SMALL LETTER O WITH DOUBLE ACUTE
U+015E    ?    c5 9e    LATIN CAPITAL LETTER S WITH CEDILLA
U+016F    ?    c5 af    LATIN SMALL LETTER U WITH RING ABOVE

En waarschijnlijk alle tekens op deze pagina: http://www.utf8-chartable.de/unicode-utf8-table.pl?start=256


Toevoeging op 18/04/2013 11:37:12:

Toevoeging, als ik bovenstaande hex waardes gebruik en daarmee de string invoer dan krijg ik uiteindelijk wel de juiste string op mijn scherm:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
UPDATE locations
SET location_name = CONCAT(UNHEX('C59E'), UNHEX('C4B1'), 'mkent')
WHERE location_id = 3031;

Maar dit is natuurlijk niet een echt werkbare oplossing.

Toevoeging op 18/04/2013 12:32:25:

Niet de oplossing dus, maar het gaf me wel een aanzet tot het volgende.

Eerst converteer ik de string naar een hexadecimale weergave van de string:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php
$hex
='';
$l = strlen( $point['name'] )
for ( $i=0; $i < $l; $i++ ){
  $hex .= dechex( ord( $point['name'][$i] ) );
}

$point['name'] = $hex;
?>

Vervolgens voer ik dit in de database in waarbij ik de hexadecimale string dus weer converteer naar een gewone string met een mysql functie (UNHEX).
Dit werkt. Alle karakters krijg ik nu op een juiste manier op mijn scherm te zien. Of het nu echt een perfecte oplossing is iets anders.

Als iemand dit nog leest ben ik zeer benieuwd naar opmerkingen en andere ideeen.
 
Roy -

Roy -

18/04/2013 19:09:56
Quote Anchor link
Ik begrijp dat je overal UTF-8 gebruikt cq ingesteld hebt? Zie ook: http://royduineveld.nl/blog/php/103/utf-8-karakterset/

In het geval dat dat goed zit kan je iconv nog proberen. Een tijd geleden heb ik zelf ook zitten stoeien met een soortgelijk probleem bij het uitlezen van verschillende RSS feeds met verschillende coderingen/karaktersets. Hetgeen dat bij mij de oplossing was:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$string
= iconv("UTF-8", "UTF-8//TRANSLIT", $string);
?>


Mocht dit ook niet werken kan je eventueel nog stoeien met mb_detect_encoding en deze waarde als eerste parameter bij iconv gebruiken. Bijvoorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
$string
= iconv((mb_detect_encoding($string,'UTF-8, ISO-8859-1') ?: 'UTF-8'), "UTF-8//TRANSLIT", $string);
?>
Gewijzigd op 18/04/2013 19:10:15 door Roy -
 



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.