Подтвердить что ты не робот

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 ...
4b9b3361

Ответ 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