json_encode() 非 utf-8 字符串?

2022-08-30 14:53:42

所以我有一个字符串数组,所有字符串都使用系统默认的ANSI编码,并且是从SQL数据库中提取的。因此,有256种不同的可能字符字节值(单字节编码)。
有没有办法让我开始工作并显示这些字符,而不必在我的所有字符串上使用,最终得到这样的东西?json_encode()utf8_encode()\u0082

或者这是JSON的标准吗?


答案 1

有没有办法让json_encode()工作并显示这些字符,而不必在所有字符串上使用utf8_encode()并最终得到“\u0082”之类的东西?

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

使用 PHP 将 ANSI 转换为 UTF-8

json_encode仅适用于编码字符串。如果需要从编码的字符串成功创建有效,则需要将其重新编码/转换为 first。然后将按照文档记录工作。UTF-8jsonANSIUTF-8json_encode

要将编码从(更准确地说,我假设您有一个编码字符串,这是流行的,但错误地称为)转换为您可以使用mb_convert_encoding()函数:ANSIWindows-1252ANSIUTF-8

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

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

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

关于utf8_encode()的说明

utf8_encode() 仅适用于 , 不适用于 。因此,当您通过该函数运行该字符串时,您将销毁该字符串中的部分字符。Latin-1ANSI


相关:什么是 ANSI 格式?


有关返回内容的更细粒度的控制,请参阅预定义常量列表(PHP 版本相关,包括.PHP 5.4,某些常量保持未记录状态,并且仅在源代码中可用到目前为止)。json_encode()

以迭代方式更改数组的编码(PDO 注释)

正如您在注释中所写的那样,在将函数应用于数组时遇到问题,下面是一些代码示例。在使用 之前,始终需要更改编码。这只是一个标准的数组操作,对于更简单的迭代情况:json_encodepdo::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 );
}

答案 2

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。


推荐