У меня есть 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.) 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.