【问题标题】:Charset - json_encode with utf-8字符集 - 带有 utf-8 的 json_encode
【发布时间】:2017-08-11 22:47:13
【问题描述】:

我知道这个问题有很多问题,并且我已经阅读了大部分问题,当然包括“UTF-8 all way through”。
按照这些示例和提示,我将所有内容简化为这个最小示例 - 不幸的是,在对数组进行 json_encoding 之后仍然不会打印德语变音符号ö
这是问题 - 为什么?我还能做什么?)

<?php
    error_reporting(E_ALL);
    header('Content-Type: text/html; charset=UTF-8');
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<?php
echo "<br>ini_get('default_charset') ". ini_get('default_charset')."<br>"; // nothing shown
// if (!ini_set('default_charset', 'utf-8')) {  // won't work (I guess I'm not allowed to do that)
// echo "could not set default_charset to utf-8<br>";
// }

echo "Köln"; // yay! displays "Köln" as expected

$darr = Array();
$locationString = mb_convert_encoding("location", "UTF-8");
$darr[$locationString] = mb_convert_encoding("Köln", "UTF-8");
$json = json_encode($darr); 
echo $json;
// output:
// {"plain":"K\u00f6ln","utf_encode":"K\u00c3\u00b6ln","utf_decode":"K"}
// dah? why?
$array = json_decode($json); 
var_dump($array);
// ... even worse: "Köln"

phpinfo();
?>
</body>
</html>

相关系统信息:
php 5.2.5(是的,我知道。我无法更改)

来自 phpinfo():
default_charset 无值

json
启用 json 支持
json 版本 1.2.1

mbstring
启用多字节支持
多字节字符串引擎 libmbfl

mbstring.encoding_translation 关 关
这可能是我的问题吗?

...是的,php 文件在 sublimeText 中编码为 utf-8(没有 BOM)。通过 FileZilla 提交给服务器一次作为 ASCII,一次二进制,没有变化。

【问题讨论】:

    标签: php json utf-8


    【解决方案1】:

    使用 json_encode 编码 unicode 数据时,您应该使用 JSON_UNESCAPED_UNICODE 标志:

    $json = json_encode($darr, JSON_UNESCAPED_UNICODE); 
    

    以上内容自 php 5.4.0 起可用。

    对于旧版本,您可以尝试使用此功能:

    function unicode_json_encode($arr) {
            //convmap since 0x80 char codes so it takes all multibyte codes (above ASCII 127). So such characters are being "hidden" from normal json_encoding
            array_walk_recursive($arr, function (&$item, $key) { if (is_string($item)) $item = mb_encode_numericentity($item, array (0x80, 0xffff, 0, 0xffff), 'UTF-8'); });
            return mb_decode_numericentity(json_encode($arr), array (0x80, 0xffff, 0, 0xffff), 'UTF-8');
    }
    

    以上函数取自json_encode page in php.net中的cmets

    【讨论】:

    • 是的,我试过了。不幸的是,这会引发错误 - 我猜我的 php 版本太旧了? '注意:使用未定义的常量'
    • 是的,PHP 5.4.0 以后恐怕会这样
    • hmpf.... 我正在尝试的只是以可用的格式备份数据以移动到一个新的、更好的服务器....真是太可惜了。
    • 检查我的答案中的更新,它可能会在您迁移到较新的服务器时对您有所帮助:)
    • 嗯,它给了我与json_decode(json_encode($darr)) 相同的输出。我想我必须放弃。 php太老了。还是谢谢!
    【解决方案2】:

    您根本没有告诉 PHP 在将数据编码为 JSON 时不要转义字符。

    来自the manual

    JSON_UNESCAPED_UNICODE(整数)
    按字面编码多字节 Unicode 字符(默认转义为 \uXXXX)。自 PHP 5.4.0 起可用。

    所以:

    $array = json_decode($json, JSON_UNESCAPED_UNICODE); 
    

    【讨论】:

    • 是的,我试过了。不幸的是,这会引发错误 - 我猜我的 php 版本太旧了? '注意:使用未定义的常量'
    • @Jeff: “自 PHP 5.4.0 起可用”
    • 是的,你的 PHP 版本太旧了……什么都做不了。 Upgrade to something they provide security updates for.
    • 我喜欢“为任何事”......我知道。这就是为什么我想以可用的格式导出数据...
    • 带有转义 Unicode 字符的 JSON 是可用的(尽管使用的字节数比实际需要的多)。任何 JSON 解析器都会愉快地解码它们。
    猜你喜欢
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 2011-02-16
    • 2016-06-09
    • 2011-05-03
    相关资源
    最近更新 更多