Encoding van speciale characters
Ik krijg data vanuit een Oracle database aangeleverd als:
Angélique, Samão, Tümos.
Deze plaats ik 1 : 1 in de MySQL database. Deze namen zoals hierboven staan ook letterlijk in MySQL database.
Vervolgens wil ik die presenteren middels HTML, met htmlentities. (De andere method htmlspecialchars heb ik ook geprobeerd.)
Zonder deze functie krijg ik vreemde karakters.
Maar met deze functie gaan de namen als Angélique, Samão correct, echter de naam Tümos wordt T�mos!!???
Ik heb gegoogled, met verschillende character sets gespeeld, niets helpt.
Heeft iemand een idee waar dit aan zou kunnen liggen.
Nico
Als een daarvan niet UTF-8 geschikt is, zal je zulke vreemde karakters zien.
--
De html page stond op de 'korte' versie:
heb ik veranderd in de 'lange' versie:
Ik neem dat is wat je bedoeld Ariën of nog iets anders?
Maar wat ik enerzijds niet goed begrijp is dat é en ã correct geconverteerd worden en ü niet? Dat vind ik opmerkelijk in deze.
Nico
Gewijzigd op 23/11/2018 14:38:35 door nkamp Kamp van de
En heb je ook de character-set bij de databaseconnectie goed ingesteld?
Vervolgens dit uitgevoerd:
Met als resultaat:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
# Variable_name, Value
character_set_client, 'utf8'
character_set_connection, 'utf8'
character_set_database, 'utf8'
character_set_filesystem, 'binary'
character_set_results, 'utf8'
character_set_server, 'latin1'
character_set_system, 'utf8'
character_sets_dir, 'C:\\xampp\\mysql\\share\\charsets\\'
collation_connection, 'utf8_general_ci'
collation_database, 'utf8_general_ci'
collation_server, 'latin1_swedish_ci'
?>
# Variable_name, Value
character_set_client, 'utf8'
character_set_connection, 'utf8'
character_set_database, 'utf8'
character_set_filesystem, 'binary'
character_set_results, 'utf8'
character_set_server, 'latin1'
character_set_system, 'utf8'
character_sets_dir, 'C:\\xampp\\mysql\\share\\charsets\\'
collation_connection, 'utf8_general_ci'
collation_database, 'utf8_general_ci'
collation_server, 'latin1_swedish_ci'
?>
De connectie staat ook op UTF-8. Ik heb voor de zekerheid MySQL nog een keer gestopt en geherstart.
Nico
En zijn je tabellen ook allemaal voorzien van de juiste collatie?
Gebruik je MySqli ?
Nu heb ik dit specifiek voor de tabel uitgevoerd:
Code (php)
1
2
3
2
3
<?php
alter table `<tabel naam>` convert to character set utf8 collate utf8_unicode_ci;
?>
alter table `<tabel naam>` convert to character set utf8 collate utf8_unicode_ci;
?>
TABLE_TYPE = BASE TABLE
ENGINE = MyISAM
TABLE COLLATION = utf8_unicode_ci
En euh... nee dit is geen MySQLi, maar nog MySQL. Ok let op, mocht dit het probleem vormen... dit is een applicatie die vervangen GAAT worden door PHP7, maar in de tussentijd moet dit nog wel blijven werken. Is ook oud PHP5.1 - weet ik, weet ik, weet ik
Maar stel dat MySQLi het probleem is waarom wordt dan het ene karakter als é resp. ã correct geconverteerd en ü niet?
Laat eens zien hoe je je database-connectie maakt.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
function fr_mysql_connection($user,$pass,$db,$host) {
if($link=mysql_connect($host,$user,$pass)) {
if (mysql_select_db($db,$link)) {
return($link);
}
}
return(FALSE);
}
?>
function fr_mysql_connection($user,$pass,$db,$host) {
if($link=mysql_connect($host,$user,$pass)) {
if (mysql_select_db($db,$link)) {
return($link);
}
}
return(FALSE);
}
?>
En deze $link wordt in een $GLOBAL['db_connecties'][$database_type][$connection_name] geplaatst. Ik heb dit ook nog nooit zo gezien maar het werkt, al heb ik hier niet een goed gevoel bij of dit een goeie manier is. Maar zoals ik zei het werkt.
?>
Gewijzigd op 23/11/2018 16:16:04 door nkamp Kamp van de
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
function fr_mysql_connection($user,$pass,$db,$host) {
if($link=mysql_connect($host,$user,$pass)) {
mysql_set_charset('utf8', $link);
if (mysql_select_db($db,$link)) {
return($link);
}
}
return(FALSE);
}
?>
function fr_mysql_connection($user,$pass,$db,$host) {
if($link=mysql_connect($host,$user,$pass)) {
mysql_set_charset('utf8', $link);
if (mysql_select_db($db,$link)) {
return($link);
}
}
return(FALSE);
}
?>
Helpt dat?
Gewijzigd op 23/11/2018 16:30:53 door Ozzie PHP
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
function fr_mysql_connection($user,$pass,$db,$host) {
if($link=mysql_connect($host,$user,$pass)) {
mysql_set_charset('utf8', $link);
if (mysql_select_db($db,$link)) {
return($link);
}
}
return(FALSE);
}
?>
function fr_mysql_connection($user,$pass,$db,$host) {
if($link=mysql_connect($host,$user,$pass)) {
mysql_set_charset('utf8', $link);
if (mysql_select_db($db,$link)) {
return($link);
}
}
return(FALSE);
}
?>
Wat is het verschil?
Wanneer de data niet goed geïmporteerd is maakt het niet uit wat je doet. MySQL gaat er immers vanuit dat deze correct geëncodeerd is. Hier een ALTER TABLE overheen gooien gaat je probleem niet oplossen. De collation heeft hier helemaal niets mee te maken - collation gaat over sorteren en matching, niet over de character encodering zelf.
De enige remedie is de data correct importeren of repareren.
En vervolgens is het zaak dat je deze op de juiste manier weergeeft, anders zie je nog steeds wiebertjes, vraagtekens en andere vreemde karakters op je scherm, maar dat heeft dan dus weer niets met het wel of niet juist geëncodeerd zijn te maken...
Nota Bene: utf8 is een subset van UTF-8 dus uit oogpunt van maximale compatibiliteit is het misschien beter om alle tabellen op te zetten als utf8mb4.
Gewijzigd op 23/11/2018 16:48:02 door Thomas van den Heuvel
@Ozzie mysqli functies zijn niet compatible met mysql functies. Dat is het verschil.
Snap ik, maar ik bedoel wat het verschil is tussen jouw en mijn code. Ik kijk blijkbaar ergens overheen.
@Thomas wanneer is de data niet goed geïmporteerd? Ik bedoel ik haal de data op vanuit een Oracle database. Daarin staat het op deze wijze é, ü, ã. Zo heb ik het nu ook letterlijk in mijn MySQL database nu staan weliswaar mbv. de functie 'mysql_real_escape_string'.
Dus denk ik nu: het staat letterlijk hetzelfde in twee dBsen en dus is het goed, of...?
Nu wil ik het presenteren op het scherm en dan gaat het fout...
Of bedoel je nu te zeggen dat ik het met 'wiebertjes/vraagtekens' in de MySQL database moet weg schrijven?
Overigens wat is nu de beste of meest geschikte:
- collatie?
- karakterset?
- database engine?
En wat zet je dan in je HTML page, zodat het altijd werkt?
Zijn daar regels voor?
<meta charset="UTF-8">
Allereerst is het handig als duidelijk is wat een character encoding is (interne link), en vervolgens de realisatie dat alle tekst een character encoding heeft.
Afhankelijk van character encoding is de ene é de andere niet op byte-niveau.
Ook jouw Oracle database houdt een bepaalde character encoding aan. Een eerste stap voor correcte import zou het uitvogelen van de character encoding zijn.
Dan set_charset(X). Je moet set_charset(X) zien als het contract tussen jou en je MySQL-database. Hiermee leg je vast dat:
- jij data aanlevert met character encoding X
- MySQL haar best doet om alle data terug te geven met character encoding X
Wanneer jij geen character encoding instelt bij het maken van een connectie veronderstelt MySQL waarschijnlijk de default character encoding "latin1". MySQL is zelf best slim. Als deze ziet dat jij dus wilt communiceren in "latin1" maar de data in jouw tabellen zijn utf8 dan zal MySQL:
- als deze data ontvangt omzetten naar utf8
- als deze data uitgeeft weer terug vertalen naar latin1
MySQL gaat hier verder wel uit van correct geëncodeerde data. Als deze niet klopt kun je ook niet verwachten dat MySQL dit voor je rechtbuigt (al dan niet met vertalingen tussen verschillende character encoderingen). Het is beter om dingen altijd expliciet in te stellen in plaats van uit te gaan van mogelijk afwijkende defaults.
Hiernaast is het handig om dus alles in de pas te laten lopen:
- de connectie met je database
- de databasetabellen
- de DATA in de tabellen :p
- Content-Type header en/of meta tag
En ja, collation is iets anders dan character encodering (interne link).
Gewijzigd op 23/11/2018 21:11:19 door Thomas van den Heuvel