所以我有一个字符串数组,所有字符串都使用系统默认的ANSI编码,并从sql数据库中提取。因此,有256种不同的可能字符字节值(单字节编码)。有没有办法让json_encode()工作并显示这些字符而不必在我的所有字符串上使用utf8_encode()并最终得到像“\ u0082”这样的东西?
或者这是json的标准?
答案 0 :(得分:33)
有没有办法可以让json_encode()工作并显示这些字符,而不必在我的所有字符串上使用utf8_encode(),最后得到像“\ u0082”这样的东西?
如果你有ANSI编码的字符串,使用utf8_encode()
是错误的函数来处理这个问题。您需要先将其正确地从ANSI转换为UTF-8。这肯定会减少json输出中的\u0082
等Unicode转义序列的数量,但从技术上来说这些序列are valid for json,你一定不要害怕它们。
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()
仅适用于Latin-1
,不适用于ANSI
。因此,当您通过该函数运行时,您将销毁该字符串中的部分字符。
要对json_encode()
返回的内容进行更精细的控制,请参阅list of predifined constants(依赖于PHP版本,包括PHP 5.4,某些常量仍未记录,仅在源代码中可用到目前为止)。
正如您在评论中写道,将函数应用于数组时遇到问题,这里有一些代码示例。在使用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 );
}
答案 1 :(得分:10)
JSON标准 ENFORCES 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在使用json_encode()
时强制执行unicode编码的原因。
至于“默认ANSI”,我很确定您的字符串是在Windows-1252中编码的。它被错误地称为ANSI。
答案 2 :(得分:4)
<?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(整数) 从字面上对多字节Unicode字符进行编码(默认为以\ uXXXX转义)。从PHP 5.4.0开始提供。
http://php.net/manual/en/json.constants.php#constant.json-unescaped-unicode
答案 3 :(得分:-2)
我发现以下答案是针对嵌套数组的类似问题,而不是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 ));
答案 4 :(得分:-3)
json_encode($str,JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT);
将基于ANSI的窗口转换为utf-8,错误将不复存在。
答案 5 :(得分:-4)
请改用:
<?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的评论中复制。请务必阅读评论。它们很有用。