繁体   English   中英

json_encode() 非 utf-8 字符串?

[英]json_encode() non utf-8 strings?

所以我有一个字符串数组,所有字符串都使用系统默认的ANSI编码并从 SQL 数据库中提取。 所以有 256 个不同的可能字符字节值(单字节编码)。
有没有办法让json_encode()工作并显示这些字符,而不必在我的所有字符串上使用utf8_encode()并以像这样的东西结束?

或者那是 JSON 的标准?

有没有办法让 json_encode() 工作并显示这些字符,而不必在我的所有字符串上使用 utf8_encode() 并以“\‚”之类的东西结束?

如果您有 ANSI 编码的字符串,则使用utf8_encode()是处理此问题的错误函数。 您需要先将其从 ANSI 正确转换为 UTF-8。 这肯定会减少 json 输出中像这样的 Unicode 转义序列的数量,但从技术上讲,这些序列对 json 有效,您不必害怕它们。

使用 PHP 将 ANSI 转换为 UTF-8

json_encode可与UTF-8编码字符串。 如果您需要从ANSI编码的字符串成功创建有效的json ,则需要先将其重新编码/转换为UTF-8 然后json_encode将按照记录工作。

要将编码从ANSI (更准确地说,我假设您有一个Windows-1252编码的字符串,它很流行但被错误地称为ANSI )到UTF-8您可以使用mb_convert_encoding()函数:

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

PHP 中另一个可以转换字符串编码/字符集的函数称为基于libiconv 的iconv 您也可以使用它:

$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 在使用json_encode()时强制执行 unicode 编码的原因。

至于“默认 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_UNICODE (integer) 按字面编码多字节 Unicode 字符(默认转义为 \\uXXXX)。 自 PHP 5.4.0 起可用。

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

我找到了以下类似问题的答案,其中嵌套数组不是 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);

这会将基于 Windows 的 ANSI 转换为 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 manual的注释中复制。 总是阅读评论。 它们很有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM