【问题标题】:Why does the PHP json_encode function convert UTF-8 strings to hexadecimal entities?为什么 PHP json_encode 函数将 UTF-8 字符串转换为十六进制实体?
【发布时间】:2013-05-06 02:01:06
【问题描述】:

我有一个处理多种语言的 PHP 脚本。不幸的是,每当我尝试使用 json_encode 时,任何 Unicode 输出都会转换为十六进制实体。这是预期的行为吗?有没有办法将输出转换为 UTF-8 字符?

这是我看到的一个例子:

输入

echo $text;

输出

База данни грешка.

输入

json_encode($text);

输出

"\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u0438 \u0433\u0440\u0435\u0448\u043a\u0430."

【问题讨论】:

    标签: php encoding json


    【解决方案1】:

    从 PHP/5.4.0 开始,有一个名为 JSON_UNESCAPED_UNICODE 的选项。看看吧:

    https://php.net/function.json-encode

    因此你应该尝试:

    json_encode( $text, JSON_UNESCAPED_UNICODE );
    

    【讨论】:

    • 啊哈。谢谢!我应该更仔细地阅读文档。谢谢。
    • JSON_UNESCAPED_UNICODE 是在 PHP 5.4.0 中引入的,在早期版本中不可用。在早期版本中使用它时,您将收到此错误:“警告:json_encode() 期望参数 2 很长,字符串在...中给出”。有关 5.3 解决方案,请参阅下面 CertaiN 的答案。
    • 这也适用于丹麦字母 Æ,æ,Ø,ø,Å,å 谢谢!
    • 太棒了,这就是我要找的答案!
    • 你刚刚救了我的命。谢谢。
    【解决方案2】:

    这是我针对各种 PHP 版本的组合解决方案。

    在我的公司,我们正在使用具有各种 PHP 版本的不同服务器,因此我必须找到适合所有人的解决方案。

    $phpVersion = substr(phpversion(), 0, 3)*1;
    
    if($phpVersion >= 5.4) {
      $encodedValue = json_encode($value, JSON_UNESCAPED_UNICODE);
    } else {
      $encodedValue = preg_replace('/\\\\u([a-f0-9]{4})/e', "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode($value));
    }
    

    学分应该转到Marco Gasiabu。 json_encode 文档中提供了 PHP >= 5.4 的解决方案。

    【讨论】:

      【解决方案3】:
      json_encode($text, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
      

      【讨论】:

        【解决方案4】:

        raw_json_encode() 函数above 没有解决我的问题(由于某种原因,回调函数在我的 PHP 5.2.5 服务器上引发了错误)。

        但这个其他解决方案确实有效。

        https://www.experts-exchange.com/questions/28628085/json-encode-fails-with-special-characters.html

        积分应该转到Marco Gasi。我只是调用他的函数而不是调用 json_encode():

        function jsonRemoveUnicodeSequences( $json_struct )
        { 
            return preg_replace( "/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode( $json_struct ) );
        }
        

        【讨论】:

          【解决方案5】:

          你喜欢设置字符集和未转义的 unicode

           header('Content-Type: application/json;charset=utf-8');  
           json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
          

          【讨论】:

            【解决方案6】:

            一种解决方案是先对数据进行编码,然后在同一个文件中对其进行解码:

            $string =json_encode($input, JSON_UNESCAPED_UNICODE) ; 
            echo $decoded = html_entity_decode( $string );
            

            【讨论】:

              【解决方案7】:

              这是预期的行为吗?

              json_encode() 仅适用于 UTF-8 编码的数据。

              也许你可以在这里得到一个答案来转换它:cyrillic-characters-in-phps-json-encode

              【讨论】:

                【解决方案8】:

                JSON_UNESCAPED_UNICODE 在 PHP 5.4 或更高版本上可用。
                以下代码适用于 5.3 版本。

                更新

                • html_entity_decodepack + mb_convert_encoding 效率更高。
                • (*SKIP)(*FAIL) 跳过反斜杠本身和 JSON_HEX_* 标志指定的字符。

                 

                function raw_json_encode($input, $flags = 0) {
                    $fails = implode('|', array_filter(array(
                        '\\\\',
                        $flags & JSON_HEX_TAG ? 'u003[CE]' : '',
                        $flags & JSON_HEX_AMP ? 'u0026' : '',
                        $flags & JSON_HEX_APOS ? 'u0027' : '',
                        $flags & JSON_HEX_QUOT ? 'u0022' : '',
                    )));
                    $pattern = "/\\\\(?:(?:$fails)(*SKIP)(*FAIL)|u([0-9a-fA-F]{4}))/";
                    $callback = function ($m) {
                        return html_entity_decode("&#x$m[1];", ENT_QUOTES, 'UTF-8');
                    };
                    return preg_replace_callback($pattern, $callback, json_encode($input, $flags));
                }
                

                【讨论】:

                • 不应该 \u 是 \U 即大写吗?
                • 不错的 PHP
                • 由于我的主机没有升级到 5.4,我一直在寻找 3 天来找到 5.3 版的解决方案。对我来说,您是救生员,由于如此完整,我宁愿将其标记为已接受的答案!
                • 修复了字符串包含\\ 时的错误。较新版本以比 \u 更高的优先级获取 \\
                • 这应该添加到php库中。干得好。
                猜你喜欢
                • 2020-10-26
                • 1970-01-01
                • 2015-04-28
                • 2010-11-16
                • 2020-02-06
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多