【问题标题】:PHP Unicode in JSONJSON 中的 PHP Unicode
【发布时间】:2013-06-03 11:42:37
【问题描述】:

我正在向我的 PHP Web 服务发送一个 JSON POST 正文,如下所示:

{
    "foo": "☺"
}

当我在 PHP 中回显正文时,我看到:

{
    "foo":"\xe2\x98\xba"
}

我也尝试发送 \uXXXX 等效项:

{
    "foo": "\u263a"
}

这更进一步,因为收到的原始 JSON 字符串有 "foo":"\\u263a",但在 json_decode 之后,值变成了 \xe2\x98\xba

当我在 JSON 响应中使用该值时,这会导致问题。我明白了:

json_encode(): Invalid UTF-8 sequence in argument

简单来说,这就是我尝试对字符串进行 JSON 编码的原因:

> php -r 'echo json_encode("\x98\xba\xe2");'
PHP Warning:  json_encode(): Invalid UTF-8 sequence in argument in Command line code on line 1

我的问题是:我怎样才能最好地将这个笑脸从我的应用程序的一端传递到另一端?

如果您能提供任何帮助,我将不胜感激。

【问题讨论】:

  • 你是如何“[...] 回响身体 [...]”的?
  • echo "\xe2\x98\xba"; 工作;显示正确的 unicode 笑脸。
  • @PleaseStand 我用error_log(file_get_contents('php://input'))将它发送到error_log。
  • @rossmcf 你能发布引发错误的行吗?
  • 您需要了解 Unicode 字符与其 UTF-8 编码之间的关系。您所展示的一切都是正确的,但上下文很重要。

标签: php json unicode


【解决方案1】:

我相信这是 json_encode 的正确行为。如果您使用以下内容:

<script>
    alert(
     <?php
       $a = "☺";
       echo json_encode($a);
     ?>
    );
</script>

HTML 输出将是 alert("\u263a");,警报将显示 ,因为 "\u263a" 是 JavaScript 中字符串的正确表示。

在 PHP 中使用 JSON_UNESCAPED_UNICODE 常量作为 json_encode 的第二个参数也是一种选择,但仅适用于 PHP 5.4.0 或更高版本。

您打算在什么情况下使用该值?


编辑:

php -r 'echo json_encode("\x98\xba\xe2");'

PHP 警告:json_encode():第 1 行命令行代码的参数中的 UTF-8 序列无效

问题是您使用了错误的字符序列。应该是

echo json_encode("\xe2\x98\xba"); // this works for me

而不是

echo json_encode("\x98\xba\xe2"); 

【讨论】:

  • 我认为您在这里有所作为。该值需要以 JSON 格式返回,这就是我遇到问题的地方。
  • @rossmcf 所以你想发送一个带有该字符的字符串作为来自 PHP 的 JSON 响应,对吧?有什么问题?如果 JSON 响应由 JavaScript 处理,即使结果是 \u263a 而不是 ,它也应该正确运行。
  • 问题是 json_encode 不会编码'\x98\xba\xe2',至少在我的 PHP 版本中是这样。
  • @rossmcf 我认为问题出在您没有向我们展示的代码中。我的猜测是存在不适当的双重转换。
  • 我刚刚为这个问题添加了更多细节。在处理字符串的内部表示,即'\x98\xba\xe2'时,似乎是json_encode的问题。
【解决方案2】:

PHP 的 json_decode() 函数在您输入的情况下表现正确,返回代表字符的 UTF-8 字节序列 (E2 98 BA)。

但是,Apache HTTPD 在将行写入错误日志之前应用了\x 转义(在函数ap_escape_logitem() 中)(就像您使用error_log() 为测试目的所做的那样)。如文件 server/gen_test_char.c 中所述,“所有 [...] 设置了高位的 8 位字符”都已转义。

【讨论】:

    【解决方案3】:

    我认为当你编码时你必须使用 json_encode({ foo": "☺"}, JSON_UNESCAPED_UNICODE)

    json_encode 函数基本上只适用于 UTF-8 编码,所以在编码之前检查字符串的编码,像这样。

     mb_check_encoding("your string", 'UTF-8') ;
    

    如果它返回 false,那么您可以使用 utf-8 转换为 utf-8

    utf8_encode("your string");
    

    【讨论】:

    • 谢谢阿伦。当我尝试您的建议时,json_encode 输出:“\u0098\u00ba\u00e2”,这是另外三个字符。
    猜你喜欢
    • 2013-07-19
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-04
    • 2013-01-09
    • 1970-01-01
    相关资源
    最近更新 更多