json кодирует() строки, отличные от utf-8?
Итак, у меня есть массив строк, и все строки используют системную кодировку ANSI по умолчанию и были извлечены из базы данных sql. Таким образом, существует 256 различных возможных значений байтов символов (однобайтовая кодировка). Есть ли способ заставить json_encode() работать и отображать эти символы вместо того, чтобы использовать utf8_encode() во всех моих строках и заканчивать такими вещами, как "\u0082"?
Или это стандарт для json?
8 answers
Есть ли способ заставить json_encode() работать и отображать эти символы вместо того, чтобы использовать utf8_encode() во всех моих строках и заканчивать такими вещами, как "\u0082"?
Если у вас есть строка в кодировке ANSI, использование utf8_encode()
является неправильной функцией для решения этой проблемы. Сначала вам нужно правильно преобразовать его из ANSI в UTF-8. Это, безусловно, уменьшит количество escape-последовательностей Юникода, таких как \u0082
, в выводе json, но технически это последовательности действительны для json, вы не должны их бояться.
Преобразование ANSI в UTF-8 с помощью PHP
json_encode
работает только с UTF-8
закодированными строками . Если вам нужно успешно создать допустимую json
из закодированной строки ANSI
, сначала вам необходимо перекодировать/преобразовать ее в UTF-8
. Тогда json_encode
будет просто работать так, как задокументировано.
Для преобразования кодировки из ANSI
(более правильно я предполагаю, что у вас есть Windows-1252
закодированная строка, которая популярна, но ошибочно упоминается как ANSI
) до UTF-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()
итерации 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 );
}
Стандарт 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
Поэтому, в строгом смысле, кодированный ANSI JSON не будет допустимым JSON; вот почему PHP применяет кодировку unicode при использовании json_encode()
.
Что касается "ANSI по умолчанию", я почти уверен, что ваши строки закодированы в Windows-1252. Он неправильно называется ANSI.
<?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_УНИКОД (целое число) Кодируйте многобайтовые символы Юникода буквально (по умолчанию используется экранирование как \uXXXX). Доступно с PHP 5.4.0.
Http://php.net/manual/en/json.constants.php#constant.json-unescaped-unicode
Да, это стандартное поведение для json в PHP
Если вы читаете документацию: http://php.net/manual/en/function.json-encode.php
Вы увидите, что он может работать только с данными в кодировке utf-8,
С другой стороны, вы можете использовать первый комментарий в: http://php.net/manual/en/function.json-encode.php#104278
И создайте свою собственную функцию кодирования/декодирования, работающую с ANSI
Для печати испанского слова я, наконец, получил решение, как показано ниже, с применением двух функций.
$conn->set_charset("utf8");
mb_convert_encoding('THE BULLOCK ÉTAGÈRE - 3 SHELVES', "UTF-8", "Windows-1252")
Где "БУЛЛОК С ТЕГОМ - 3 ПОЛКИ" эта строка взята из базы данных, поэтому у меня есть первый объект базы данных $conn, чтобы установить символ как utf8 затем я закодировал испанское слово UTF-8 в Windows-1252
Я нашел следующий ответ для аналогичной проблемы с вложенным массивом, не закодированным в кодировке 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 ));
json_encode($str,JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT);
, который преобразует ANSI на базе Windows в utf-8, и ошибки больше не будет.
Используйте это вместо:
<?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 комментариев. Всегда читайте комментарии. Они полезны.