json_encode () не строки utf-8? - PullRequest
       13

json_encode () не строки utf-8?

25 голосов
/ 07 июля 2011

Итак, у меня есть массив строк, и все строки используют системную кодировку ANSI по умолчанию и были извлечены из базы данных sql. Таким образом, существует 256 различных возможных значений символов (однобайтовая кодировка). Есть ли способ заставить json_encode () работать и отображать эти символы вместо того, чтобы использовать utf8_encode () во всех моих строках и заканчивать вещами типа "\ u0082"?

Или это стандарт для JSON?

Ответы [ 6 ]

33 голосов
/ 07 июля 2011

Есть ли способ заставить json_encode () работать и отображать эти символы, вместо того, чтобы использовать utf8_encode () во всех моих строках и заканчивая такими вещами, как "\ u0082"?

Если у вас есть строка в кодировке ANSI, использование utf8_encode() является неправильной функцией для решения этой проблемы.Вам необходимо сначала правильно преобразовать его из ANSI в UTF-8.Это, безусловно, уменьшит количество escape-последовательностей Unicode, таких как \u0082, из вывода json, но технически эти последовательности действительны для json , вы не должны их бояться.

Преобразование ANSI в UTF-8 с PHP

json_encode работает с UTF-8 закодированными строками * только 1019 * .Если вам нужно успешно создать действительный json из строки, закодированной в ANSI, вам необходимо сначала перекодировать / преобразовать его в UTF-8.Тогда json_encode будет работать так, как задокументировано.

Чтобы преобразовать кодировку из ANSI (точнее, я предполагаю, что у вас есть кодированная строка Windows-1252, которая популярна, но ошибочно называется ANSIUTF-8 вы можете использовать функцию mb_convert_encoding():

$str = mb_convert_encoding($str, "UTF-8", "Windows-1252");

Другая функция в PHP, которая может преобразовывать кодировку / кодировку строки, называется iconv на основе libiconv .Вы также можете использовать его:

$str = iconv("CP1252", "UTF-8", $str);

Примечание к utf8_encode ()

utf8_encode() работает только для Latin-1, но не для ANSI.Таким образом, вы будете уничтожать часть своих символов внутри этой строки, когда будете выполнять ее через эту функцию.


Связанный: Что такое формат ANSI?


Для более детального контроля того, что возвращает json_encode(), см. Список предопределенных констант (зависит от версии PHP, включая PHP 5.4, некоторые константы остаются недокументированными и пока доступны в исходном коде).

Изменение кодировки массива / итеративно (комментарий PDO)

Как вы написали в комментарии, у вас есть проблемы с применением функции к массиву, вот пример кода. всегда необходимо для сначала изменить кодировку перед использованием json_encode.Это просто стандартная операция с массивом, для более простого случая pdo::fetch() a foreach итерации:

while($row = $q->fetch(PDO::FETCH_ASSOC))
{
  foreach($row as &$value)
  {
    $value = mb_convert_encoding($value, "UTF-8", "Windows-1252");
  }
  unset($value); # safety: remove reference
  $items[] = array_map('utf8_encode', $row );
}
10 голосов
/ 07 июля 2011

Стандарт JSON ОБЕСПЕЧИВАЕТ кодировку Unicode . От RFC4627 :

3.  Encoding

   JSON text SHALL be encoded in Unicode.  The default encoding is
   UTF-8.

   Since the first two characters of a JSON text will always be ASCII
   characters [RFC0020], it is possible to determine whether an octet
   stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
   at the pattern of nulls in the first four octets.

           00 00 00 xx  UTF-32BE
           00 xx 00 xx  UTF-16BE
           xx 00 00 00  UTF-32LE
           xx 00 xx 00  UTF-16LE
           xx xx xx xx  UTF-8

Следовательно, в самом строгом смысле код JSON в формате ANSI не будет действительным JSON; Вот почему PHP применяет кодировку Юникод при использовании json_encode().

Что касается "ANSI по умолчанию", я уверен, что ваши строки закодированы в Windows-1252. Он неправильно называется ANSI.

6 голосов
/ 10 июня 2015
<?php
$array = array('first word' => array('Слово','Кириллица'),'second word' => 'Кириллица','last word' => 'Кириллица');
echo json_encode($array);
/*
return {"first word":["\u0421\u043b\u043e\u0432\u043e","\u041a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430"],"second word":"\u041a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430","last word":"\u041a\u0438\u0440\u0438\u043b\u043b\u0438\u0446\u0430"}
*/
echo json_encode($array,256);
/*
return {"first word":["Слово","Кириллица"],"second word":"Кириллица","last word":"Кириллица"}
*/
?>

JSON_UNESCAPED_UNICODE (integer) Кодировать многобайтовые символы Unicode буквально (по умолчанию экранировать как \ uXXXX).Доступно с PHP 5.4.0.

http://php.net/manual/en/json.constants.php#constant.json-unescaped-unicode

0 голосов
/ 25 июня 2014

Я нашел следующий ответ для аналогичной проблемы с вложенным массивом, не кодированным utf-8, который мне пришлось кодировать json:

$inputArray = array(
    'a'=>'First item - à',
    'c'=>'Third item - é'
);
$inputArray['b']= array (
          'a'=>'First subitem - ù',
          'b'=>'Second subitem - ì'
    );
 if (!function_exists('recursive_utf8')) {
  function recursive_utf8 ($data) {
     if (!is_array($data)) {
        return utf8_encode($data);
     }
     $result = array();
     foreach ($data as $index=>$item) {
        if (is_array($item)) {
           $result[$index] = array();
           foreach($item as $key=>$value) {
              $result[$index][$key] = recursive_utf8($value);
           }
        }
        else if (is_object($item)) {
           $result[$index] = array();
           foreach(get_object_vars($item) as $key=>$value) {
              $result[$index][$key] = recursive_utf8($value);   
           }
        } 
        else {
           $result[$index] = recursive_utf8($item);
        }
     }
     return $result; 
   }
}
$outputArray =  json_encode(array_map('recursive_utf8', $inputArray ));
0 голосов
/ 18 июня 2014
json_encode($str,JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT);

, который преобразует Windows на основе ANSI в utf-8, и ошибки больше не будет.

0 голосов
/ 07 июля 2011

Используйте это вместо:

<?php 
//$return_arr = the array of data to json encode 
//$out = the output of the function 
//don't forget to escape the data before use it! 

$out = '["' . implode('","', $return_arr) . '"]'; 
?>

Скопируйте из json_encode php manual комментарии. Всегда читайте комментарии. Они полезны.

...