[MySQL + PHP] Vreemde tekens in veld

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
Ik zit met de volgende situatie.

In een oude webapplicatie werd een Japanse zit zoals : " 緑色の矢印ボタンをクリックして次の質問に進んでください。" opgeslagen als "£½å“ã‚’どのように改善すべきとãŜ考えですか?".

Vervolgens wordt het uit de database gehaald en in de browser weergegeven als " 緑色の矢印ボタンをクリックして次の質問に進んでください。".

Bij het opslaan in de oude applicatie wordt het volgende met de string gedaan:

PHP:
1
2
if (get_magic_quotes_gpc()) $waarde = stripslashes($waarde);
            $waarde = MySQLi::real_escape_string($waarde);


In de nieuwe webapplicatie gebruiken we Propel, het enige bijzondere wat hij doet is "SET NAMES utf8". En het gebruiken van prepared statements.

De nieuwe applicatie slaat een zin als "緑色の矢印ボタンをクリックして次の質問に進んでください。" op als "緑色の矢印ボタンをクリックして次の質問に進んでください。" (dus hetzelfde).

Nu komt het probleem. De nieuwe applicatie laat een zin als "£½å“ã‚’どのように改善すべきとãŜ考えですか?" zien als zodanig (in de browser).

De data moet dus geconverteerd worden, maar ik zie niet waar het probleem zit en hoe ik het dus kan aanpakken. Iemand een idee?

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

  • wackmaniac
  • Registratie: Februari 2004
  • Laatst online: 10:21
Je moet je karakterset nakijken. Blijkbaar werd er bij de oude applicatie weer een conversieslag terug gemaakt naar een andere karakterset. Misschien kan RobIII hier zijn beroemde karakterset linkje weer even bij plaatsen :)

Snelle oplossing; probeer in je browser eens de karakterset in te stellen op UTF-8. Als dat werkt moet je misschien gewoon je hele applicatie UTF-8 maken, zoals Propel blijkbaar ook doet.

Read the code, write the code, be the code!


Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
Het gebeurt trouwens ook met een é of een ä.

@wackmaniac, ik zal er zo naar kijken

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

Overigens is er niks vreemds aan japanse karakters, ze zijn hooguit wat minder bekend in Nederland. Dus waarom mensen altijd beginnen over vreemde karakters...

Acties:
  • 0 Henk 'm!

  • CyBeRSPiN
  • Registratie: Februari 2001
  • Laatst online: 18:41

CyBeRSPiN

sinds 2001

cariolive23 schreef op zondag 12 december 2010 @ 11:25:
The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

Overigens is er niks vreemds aan japanse karakters, ze zijn hooguit wat minder bekend in Nederland. Dus waarom mensen altijd beginnen over vreemde karakters...
De tweede betekenis van het woord 'vreemd' is buitenlands, jij wil zeggen dat Japans niet buitenlands is? ;)
vreemd bn, bw 1 niet bekend: ik ben hier ~ 2 buitenlands; uitheems: ~ geld 3 raar, zonderling: een ~e figuur 4 niet verwant || ergens ~ van opkijken verbaasd

Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
@ cyberspin zullen we het aub ontopic houden? en @ cariolive23 Japans is niet vreemd, de tekens die opgeslagen zijn vreemd. Ik zal even kijken naar het linkje.

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-08 20:35
Je moet tegen de browser ook zeggen dat je UTF-8 stuurt. Waarschijnlijk stuur je het als latin1 (ISO-8859-1) naar de browser. Dit kun je op verschillende manieren oplossen:

PHP:
1
header('Content-Type: text/html; charset=utf-8');


Of in HTML, maar let op een header die de webserver (vanuit PHP) stuurt gaat altijd boven de meta http-equiv in HTML.
HTML:
1
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">


Daarnaast is het ook mogelijk dat je functies gebruikt zoals htmlspecialchars of htmlentities die er standaard vanuit gaan dat je in latin1 werkt.

De link die cariolive23 je geeft zou je absoluut moeten lezen.

If I can't fix it, it ain't broken.


Acties:
  • 0 Henk 'm!

  • CyBeRSPiN
  • Registratie: Februari 2001
  • Laatst online: 18:41

CyBeRSPiN

sinds 2001

Moet de oude app ook nog worden ondersteund? Anders kun je een eenmalige conversie in de database doen waarbij je de oude teksten naar UTF8 omzet.
Als de oude app nog moet worden ondersteund zou ik die aanpassen zodat ook deze de teksten in UTF8 neerzet en weergeeft, anders wordt het wel erg vervelend om de verschillende encodings te gaan detecteren en converteren..

Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
De oude app verdwijnt en inderdaad die eenmalige conversie moet gebeuren.
De vraag is inderdaad; hoe zet ik die oude teksten om naar UTF8? Het veld heeft als collate "utf8_general_ci".

Btw, ik heb het artikel gelezen, zeer interessant.

[ Voor 12% gewijzigd door Meijuh op 12-12-2010 12:51 ]

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
$encodings = array("UCS-4",
"UCS-4BE",
"UCS-4LE",
"UCS-2",
"UCS-2BE",
"UCS-2LE",
"UTF-32",
"UTF-32BE",
"UTF-32LE",
"UTF-16",
"UTF-16BE",
"UTF-16LE",
"UTF-7",
"UTF7-IMAP",
"UTF-8",
"ASCII",
"EUC-JP",
"SJIS",
"eucJP-win",
"SJIS-win",
"ISO-2022-JP",
"JIS",
"ISO-8859-1",
"ISO-8859-2",
"ISO-8859-3",
"ISO-8859-4",
"ISO-8859-5",
"ISO-8859-6",
"ISO-8859-7",
"ISO-8859-8",
"ISO-8859-9",
"ISO-8859-10",
"ISO-8859-13",
"ISO-8859-14",
"ISO-8859-15",
"byte2be",
"byte2le",
"byte4be",
"byte4le",
"BASE64",
"HTML-ENTITIES",
"7bit",
'8bit',
"EUC-CN",
"CP936",
"HZ",
"EUC-TW",
"CP950",
"BIG-5",
"EUC-KR",
"UHC",
"ISO-2022-KR",
"Windows-1251",
"Windows-1252",
"CP866",
"KOI8-R");

    foreach($encodings as $encoding) {
        $encoded = mb_convert_encoding("£½å&#8220;ã&#8218;&#8217;どのã&#8218;&#710;ã&#8224;にæ&#8221;¹å&#8211;&#8222;ã&#8482;べきとãŜè€&#402;ã&#710;でã&#8482;ã&#8249;?", "UTF-8", $encoding);
        var_dump($encoded);
    }


Hier komt op geen enkele wijze japans uit. Hoe kan ik de karakterset nu bepalen?

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

Verwijderd

Meijuh schreef op zondag 12 december 2010 @ 12:51:
De vraag is inderdaad; hoe zet ik die oude teksten om naar UTF8?
In welke encoding werd het opgeslagen bij de oude applicatie dan? Ik zou gewoon eens die code doorkijken en dan specifiek naar de wijze waarop de data verkregen werd aangezien het wel correct in de browser werd weergegeven.

Sowieso jammer dat sanitization gebruikt is, maar goed om te lezen dat het bij de nieuwe applicatie gewoon parameterization is.

Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
Ik zal de code eens doorspitten..... de gruwel....

Ik heb nu gekeken. Nu blijkt dat als ik $_POST var_dump dat het al geen Japanse karakters mee zijn.

Als ik het volgende post

非常にそう思う

ziet dit er in $_POST als volgt uit:

非常にそう思う

Hoe kan dit?

[ Voor 145% gewijzigd door Meijuh op 12-12-2010 14:51 ]

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-08 20:35
Meijuh schreef op zondag 12 december 2010 @ 14:09:
Als ik het volgende post

非常にそう思う

ziet dit er in $_POST als volgt uit:

�常�����

Hoe kan dit?
Zie mijn vorige reactie.

If I can't fix it, it ain't broken.


Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
Hmm ik heb wat gevonden. Wat lijkt te werken:

PHP:
1
2
3
4
5
6
7
8
9
10
$db->query("SET NAMES 'latin1'");
$q = "  SELECT id, waarde FROM blaat WHERE id = 318558";
$res = $db->query($q) or die($db->error);

$row = $res->fetch_assoc();
$id = $row['id'];
$hex = bin2hex($row['waarde']);
$db->query("SET NAMES 'utf8'");
$q = " UPDATE blaat SET waarde = UNHEX('$hex') WHERE id = $id";
$db->query($q) or die($db->error);


Zie: http://www.oreillynet.com...sql_data_in_latin1_t.html

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-08 20:35
Het makkelijkste om een hele database om te zetten, is een dump maken met mysqldump in UTF-8:
mysqldump -u <user> -p --default-character-set=utf8 <database naam> > <bestandsnaam>


Bewerk het bestand in een editor die met UTF-8 om kan gaan (bijv. Notepad++) en vervang "latin1" door "utf8".

Maak een nieuwe database (default charset utf8) en importeer daarin de aangepaste dump:

mysql -u <user> -p --default-character-set=utf8 <database naam> < <bestandsnaam>

If I can't fix it, it ain't broken.


Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
@Borizz mijn scriptje werkt toch nog niet optimaal, ik ga jou tip even proberen.

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

  • Meijuh
  • Registratie: December 2006
  • Laatst online: 17-03 21:08
Borizz het heeft niet gewerkt... ik ga nog even verder kijken naar mijn scriptje.

Asus EN8800GTS, Asus P5E, Intel E8400, 2x500gb Spinpoint (raid0), Zalman HP 600 watt, cnps 9500 led, creative xfi music, 4x1gb hyperX PC2 8500


Acties:
  • 0 Henk 'm!

  • kwaakvaak_v2
  • Registratie: Juni 2009
  • Laatst online: 02-06 12:29
In het geval van wat Borizz meld kan het helpen om ook even de inhoud van je mysql dump door iconv te trekken.

Driving a cadillac in a fool's parade.


Acties:
  • 0 Henk 'm!

  • Borizz
  • Registratie: Maart 2005
  • Laatst online: 24-08 20:35
kwaakvaak_v2 schreef op zondag 12 december 2010 @ 22:14:
In het geval van wat Borizz meld kan het helpen om ook even de inhoud van je mysql dump door iconv te trekken.
Dit is niet nodig als je een dump maakt in UTF-8. Mysql zorgt er dan zelf voor dat de gegevens geconverteerd worden naar UTF-8 als ze in een andere encoding in de database staan.

If I can't fix it, it ain't broken.


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 09-09 16:17

Janoz

Moderator Devschuur®

!litemod

In dit geval wel. De data staat brak in de database. De database denkt dat het de ene encoding, terwijl het de andere was. De database laten encoden zorgt er alleen maar voor dat je dezelfde rommel krijgt in een andere encoding.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1