PHP декодирование и кодирование JSON с Unicode-символами - PullRequest
31 голосов
/ 12 сентября 2011

У меня есть несколько 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 Я вижу, что есть опция unescaped_unicode для json_encode.Однако это не работает, как ожидалось.Блин, это только на php 5.4.Мне придется использовать некоторые регулярные выражения, поскольку у меня есть только 5,3.

$json = json_encode($array, JSON_UNESCAPED_UNICODE);
Warning: json_encode() expects parameter 2 to be long, string ...

Ответы [ 7 ]

30 голосов
/ 03 апреля 2016

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

json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
16 голосов
/ 12 сентября 2011

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

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

14 голосов
/ 12 сентября 2011

Судя по всему, что вы сказали, похоже, что исходная строка 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 (в UTF-8 это \x63\xb3, но эта последовательность ó в ISO 8859-1.
  • Ваше решение взлома htmlentities сработало. 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 тестирование).

7 голосов
/ 12 сентября 2011

Хакерский способ сделать 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);
4 голосов
/ 12 сентября 2011

попробуйте установить кодировку 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'};
3 голосов
/ 29 июля 2015
$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.

3 голосов
/ 12 сентября 2011

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

utf8_decode() and utf8_encode
...