PHP/json: ถอดรหัส utf8?

ฉันจัดเก็บสตริง json ที่มีอักขระบางตัว (ภาษาจีน ?) ไว้ในฐานข้อมูล mysql ตัวอย่างสิ่งที่อยู่ในฐานข้อมูล:

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

บนหน้า PHP ของฉัน ฉันแค่ทำ json_decode ของสิ่งที่ฉันได้รับจาก mysql แต่มันแสดงผลไม่ถูกต้อง มันแสดงบางอย่างเช่น "½±è§�"

ฉันพยายามดำเนินการค้นหา "SET NAMES 'utf8'" ที่จุดเริ่มต้นของไฟล์ แต่ไม่ได้เปลี่ยนแปลงอะไรเลย ฉันมีส่วนหัวต่อไปนี้บนหน้าเว็บของฉันแล้ว:

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

และแน่นอนว่าไฟล์ php ทั้งหมดของฉันเข้ารหัสเป็น UTF-8

คุณมีความคิดวิธีการแสดงอักขระ "\uXXXX" เหล่านี้อย่างสวยงามหรือไม่?


person Quentin    schedule 10.10.2011    source แหล่งที่มา
comment
อักขระเหล่านี้ควรแสดงหรือไม่: 诱惑 ?   -  person John Carter    schedule 10.10.2011
comment
แสดงให้เราเห็นมากขึ้นว่าคุณกำลังทำอะไรอยู่ echo json_decode('"\u8bf1\u60d1"'); ควรทำเคล็ดลับได้อย่างสมบูรณ์แบบ   -  person deceze♦    schedule 11.10.2011


คำตอบ (3)


Unicode ไม่ใช่ UTF-8!

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

นี่เป็น "การเข้ารหัส" ที่แปลกที่คุณมี ฉันเดาว่าอักขระแต่ละตัวในข้อความปกติจะมีความยาว "หนึ่งไบต์" (US-ASCII) จากนั้นคุณจะต้องแยกลำดับ \u.... แปลงลำดับเป็นอักขระ "สองไบต์" และแปลงอักขระนั้นด้วย iconv("unicodebig", "utf-8", $character) เป็นอักขระ UTF-8 (ดู iconv ในเอกสาร PHP) สิ่งนี้ได้ผลจากฝั่งของฉัน:

$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);

มิฉะนั้น เราต้องการข้อมูลเพิ่มเติมเกี่ยวกับวิธีการเข้ารหัสสตริงของคุณในฐานข้อมูล

person vstm    schedule 10.10.2011
comment
การเข้ารหัสเป็นผลลัพธ์ของ json_encode() (หรือตัวเข้ารหัสอื่นๆ ที่เข้ากันได้) json_decode() น่าจะเพียงพอที่จะแปลงกลับ - person John Carter; 10.10.2011
comment
@therefromhere: คุณอาจพูดถูก แต่ JSON-encoder ไม่ควรส่งออก Javascript ที่ถูกต้องใช่ไหม เนื่องจากเครื่องหมายคำพูด () ขาดหายไปเพียงข้อความและไม่ใช่ JSON จริงๆ ส่วนหนึ่งจากนั้นทางฝั่งของฉัน json_decode ก็พิมพ์ผลลัพธ์ที่ถูกต้องเช่นเดียวกับในคำตอบของคุณ - person vstm; 10.10.2011
comment
อันที่จริง ฉันคิดว่าตัวอย่างคำถามเป็นเพียงตัวอย่างของสตริง JSON ที่มีการจัดรูปแบบอย่างถูกต้องและมีขนาดใหญ่กว่า - person John Carter; 10.10.2011
comment
-1 สำหรับโซลูชันที่ซับซ้อนเกินไป echo json_decode('"\u8bf1\u60d1"'); ทำงานได้อย่างสมบูรณ์แบบ ไม่ใช่การเข้ารหัสที่แปลก แต่เป็นการเข้ารหัสจุดโค้ด Unicode ที่สมบูรณ์แบบซึ่งใช้ใน JSON - person deceze♦; 11.10.2011

ดูเหมือนว่าจะทำงานได้ดีสำหรับฉันด้วย PHP 5.3.5 บน 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);

ส่งออกสิ่งนี้:

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" />

นั่นมันปลาเฮอริ่งแดง หากคุณแสดงหน้าเว็บของคุณผ่าน http และการตอบกลับมีส่วนหัว Content-Type เมตาแท็กจะถูกละเว้น ตามค่าเริ่มต้น PHP จะตั้งค่าส่วนหัวดังกล่าว หากคุณไม่ได้กำหนดไว้อย่างชัดเจน และค่าเริ่มต้นคือ iso-8859-1

ลองกับบรรทัดนี้:

<?php
header("Content-Type: text/html; charset=UTF-8");
person troelskn    schedule 10.10.2011
comment
ไม่ได้เปลี่ยนแปลงอะไรเลย ฉันต้องพูดถึงด้วยว่า Firefox บอกว่าหน้านั้นเป็น UTF8 ดังนั้นฉันเดาว่าส่วนหัวนั้นดีอยู่แล้วใช่ไหม - person Quentin; 10.10.2011