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 тоже не работает.

Edit Я вижу, что для 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 ... 

Судя по всему, что вы сказали, похоже, что исходная строка Odómetro вы имеете дело, закодирована с ISO 8859-1, а не UTF-8.

Вот почему я так думаю:

  • json_encode создавал синтаксический вывод после utf8_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 solution работало. 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 ).

JSON_UNESCAPED_UNICODE был добавлен в PHP 5.4, поэтому, похоже, вам нужно обновить версию PHP, чтобы воспользоваться ею. 5.4 еще не выпущен! 🙁

В QA есть кандидат на выпуск альфа-версии 5.4, но если вы хотите играть на своей машине разработки.

Я нашел следующий способ исправить эту проблему … Надеюсь, это может вам помочь.

 json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); 

Хакерный способ сделать 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); 

попробуйте установить кодировку 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'}; 

Попробуйте использовать:

 utf8_decode() and utf8_encode 
 $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.