PHP-декодирование и кодирование json с символами Unicode
У меня есть json Мне нужно декодировать, изменять, а затем кодировать, не испорчая никаких символов.
Если у меня есть символ Юникода в строке json, он не будет декодироваться. Я не уверен, почему, поскольку json.org говорит, что строка может содержать: any-Unicode-character- except-"-or-\-or- control-character
. Но это также не работает в python.
{"Tag":"Odómetro"}
Я могу использовать utf8_encode, который позволит декодировать строку с помощью json_decode, однако персонаж попадает в нечто другое. Это результат print_r массива результатов. Два символа.
[Tag] => Odómetro
Когда я снова закодирую массив, персонаж сбежал в ascii, что верно в соответствии со спецификацией json:
"Tag"=>"Od\u00f3metro"
Есть ли способ избежать этого? json_encode не дает такой опции, utf8_encode тоже не работает.
Изменить. Я вижу, что для json_encode есть опция unescaped_unicode. Однако он работает не так, как ожидалось. О, черт, это только на php 5.4. Мне придется использовать некоторое регулярное выражение, поскольку у меня есть только 5.3.
$json = json_encode($array, JSON_UNESCAPED_UNICODE);
Warning: json_encode() expects parameter 2 to be long, string ...
Ответы
Ответ 1
Судя по всему, что вы сказали, кажется, что исходная строка Odómetro
, с которой вы имеете дело, кодируется с помощью стандарта ISO 8859-1, а не UTF-8.
Вот почему я так думаю:
-
json_encode
созданный синтаксический вывод после запуска строки ввода через utf8_encode
, которая преобразуется из ISO 8859-1 в UTF-8.
- Вы сказали, что при использовании
print_r
вы получили "искаженный" вывод, после того, как выполнили utf8_encode
, но полученный вами результат на самом деле был именно тем, что произошло бы, пытаясь разобрать текст UTF-8 как ISO 8859-1 ( - \x63\xb3
в UTF-8, но эта последовательность ó
в ISO 8859-1.
- Работало ваше решение
htmlentities
hackaround. htmlentities
должен знать, что кодировка входной строки будет работать правильно. Если вы не укажете один, он принимает ISO 8859-1. (html_entity_decode
, смутно, по умолчанию используется UTF-8, поэтому ваш метод имел эффект преобразования из ISO 8859-1 в UTF-8.)
- Вы сказали, что у вас такая же проблема в Python, которая, похоже, исключает PHP из-за проблемы.
PHP будет использовать экранирование \uXXXX
, но, как вы отметили, это действительно JSON.
Итак, похоже, вам нужно настроить ваше соединение с Postgres, чтобы оно передало вам строки UTF-8. В руководстве по PHP указано, что вы сделаете это, добавив options='--client_encoding=UTF8'
в строку подключения. Также существует вероятность неправильного кодирования данных, хранящихся в базе данных. (Вы можете просто использовать utf8_encode
, но это будет поддерживать только символы, которые являются частью ISO 8859-1).
Наконец, как заметил еще один ответ, вам нужно убедиться, что вы объявляете правильную кодировку с заголовком HTTP или иным образом (конечно, эта конкретная проблема могла быть только артефактом среды, в которой вы делали ваш тест print_r
).
Ответ 2
Я нашел следующий способ исправить эту проблему... Надеюсь, это может вам помочь.
json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
Ответ 3
JSON_UNESCAPED_UNICODE
был добавлен в PHP 5.4, поэтому вам кажется, что вам нужно обновить версию PHP, чтобы воспользоваться ею. 5.4 еще не выпущен!: (
В QA существует 5.4 альфа-релиз, но если вы хотите играть на своей машине разработки.
Ответ 4
Хакерный способ выполнения JSON_UNESCAPED_UNICODE в PHP 5.3. Действительно разочарован поддержкой PHP json. Возможно, это поможет кому-то другому.
$array = some_json();
// Encode all string children in the array to html entities.
array_walk_recursive($array, function(&$item, $key) {
if(is_string($item)) {
$item = htmlentities($item);
}
});
$json = json_encode($array);
// Decode the html entities and end up with unicode again.
$json = html_entity_decode($rson);
Ответ 5
попробуйте установить utf-8
кодировку на странице:
header('content-type:text/html;charset=utf-8');
это работает для меня:
$arr = array('tag' => 'Odómetro');
$encoded = json_encode($arr);
$decoded = json_decode($encoded);
echo $decoded->{'tag'};
Ответ 6
$json = array('tag' => 'Odómetro'); // Original array
$json = json_encode($json); // {"Tag":"Od\u00f3metro"}
$json = json_decode($json); // Od\u00f3metro becomes Odómetro
echo $json->{'tag'}; // Odómetro
echo utf8_decode($json->{'tag'}); // Odómetro
Вы были близки, просто используйте utf8_decode.
Ответ 7
Попробуйте использовать:
utf8_decode() and utf8_encode
Ответ 8
Для кодирования массива, содержащего специальные символы, ISO 8859-1 до UTF8. (Если utf8_encode & utf8_decode не подходит для вас, это может быть вариант)
Все, что находится в ISO-8859-1, должно быть преобразовано в UTF8:
$utf8 = utf8_encode('이 감사의 마음을 전합니다!'); //contains UTF8 & ISO 8859-1 characters;
$iso88591 = mb_convert_encoding($utf8, 'ISO-8859-1', 'UTF-8');
$data = $iso88591;
Кодировка должна работать после этого:
$encoded_data = json_encode($data);
Конвертировать UTF-8 в & из ISO 8859-1