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)


Юникод это не 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-кодировщик не должен выводить действительный 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