Php/json: memecahkan kode utf8?

Saya menyimpan string json yang berisi beberapa karakter (Cina?) di database mysql. Contoh isi database:

normal.text.\u8bf1\u60d1.rest.of.text

Di halaman PHP saya, saya hanya melakukan json_decode dari apa yang saya terima dari mysql, tetapi tidak ditampilkan dengan benar, ini menunjukkan hal-hal seperti "½±è§�"

Saya sudah mencoba menjalankan kueri "SET NAMES 'utf8'" di awal file saya, tidak mengubah apa pun. Saya sudah memiliki header berikut di halaman web saya:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Dan tentu saja semua file php saya dikodekan dalam UTF-8.

Apakah Anda tahu cara menampilkan karakter "\uXXXX" ini dengan baik?


person Quentin    schedule 10.10.2011    source sumber
comment
Apakah ini karakter yang harus ditampilkan: 诱惑 ?   -  person John Carter    schedule 10.10.2011
comment
Tunjukkan kepada kami lebih banyak tentang apa yang sebenarnya Anda lakukan. echo json_decode('"\u8bf1\u60d1"'); seharusnya melakukan triknya dengan baik.   -  person deceze♦    schedule 11.10.2011


Jawaban (3)


Unicode bukan UTF-8!

$ echo -en '\x8b\xf1\x60\xd1\x00\n' | iconv -f unicodebig -t utf-8
诱惑

Ini adalah "pengkodean" aneh yang Anda miliki. Saya kira setiap karakter teks normal panjangnya "satu byte" (US-ASCII)? Kemudian Anda harus mengekstrak urutan \u...., mengonversi urutan dalam karakter "dua byte" dan mengonversi karakter tersebut dengan iconv("unicodebig", "utf-8", $character) menjadi karakter UTF-8 (lihat iconv dalam dokumentasi PHP). Ini berhasil di pihak saya:

$in = "normal.text.\u8bf1\u60d1.rest.of.text";

function ewchar_to_utf8($matches) {
    $ewchar = $matches[1];
    $binwchar = hexdec($ewchar);
    $wchar = chr(($binwchar >> 8) & 0xFF) . chr(($binwchar) & 0xFF);
    return iconv("unicodebig", "utf-8", $wchar);
}

function special_unicode_to_utf8($str) {
    return preg_replace_callback("/\\\u([[:xdigit:]]{4})/i", "ewchar_to_utf8", $str);
}

echo special_unicode_to_utf8($in);

Jika tidak, kami memerlukan informasi lebih lanjut tentang bagaimana string Anda dalam database dikodekan.

person vstm    schedule 10.10.2011
comment
Pengkodean adalah hasil dari json_encode() (atau pembuat enkode lain yang kompatibel), json_decode() seharusnya cukup untuk mengubahnya kembali. - person John Carter; 10.10.2011
comment
@therefromhere: Anda mungkin benar, tetapi bukankah encoder JSON harus menghasilkan Javascript yang valid? Karena tanda kutip () tidak ada hanya teksnya dan bukan JSON sebenarnya. Selain itu, di sisi saya json_decode juga mencetak hasil yang benar, seperti pada jawaban Anda. - person vstm; 10.10.2011
comment
Memang, saya berasumsi contoh pertanyaan adalah cuplikan string JSON yang lebih besar dan diformat dengan benar. - person John Carter; 10.10.2011
comment
-1 untuk solusi yang terlalu rumit. echo json_decode('"\u8bf1\u60d1"'); berfungsi dengan baik. Ini juga bukan pengkodean yang aneh, ini adalah pengkodean titik kode Unicode yang sangat bagus yang digunakan dalam JSON. - person deceze♦; 11.10.2011

Ini sepertinya berfungsi dengan baik bagi saya, dengan PHP 5.3.5 di Ubuntu 11.04:

<?php
header('Content-Type: text/plain; charset="UTF-8"');
$json = '[ "normal.text.\u8bf1\u60d1.rest.of.text" ]';

$decoded = json_decode($json, true);

var_dump($decoded);

Keluaran ini:

array(1) {
  [0]=>
  string(31) "normal.text.诱惑.rest.of.text"
}
person John Carter    schedule 10.10.2011

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Itu ikan haring merah. Jika Anda menyajikan halaman Anda melalui http, dan responsnya berisi header Content-Type, maka tag meta akan diabaikan. Secara default, PHP akan menyetel header seperti itu, jika Anda tidak melakukannya secara eksplisit. Dan defaultnya ditetapkan sebagai iso-8859-1.

Coba dengan baris ini:

<?php
header("Content-Type: text/html; charset=UTF-8");
person troelskn    schedule 10.10.2011
comment
Tidak mengubah apa pun. Saya juga harus menyebutkan bahwa firefox mengatakan halamannya dalam UTF8 jadi saya kira headernya sudah bagus? - person Quentin; 10.10.2011