【问题标题】:PHP json_decode with long strings and special characters带有长字符串和特殊字符的 PHP json_decode
【发布时间】:2016-01-25 18:52:40
【问题描述】:

我收到来自 API 服务器的 JSON 响应。响应的结果数量会有所不同,并且可能包含多个带有长字符串的键。这些长字符串也可能包含特殊字符。

这是我在 json_decode 之后的示例数组:

Array ( [0] => Array ( [id] => 1535497 [tid] => 6970000 [text] => Hello :) error is back! It's quite annoying! [dFlag] => 1 [iFlag] => [rFlag] => [member] => [contact] => Array ( [id] => 187 [name] => User Name [_info] => Array ( [contact_href] => https://url/187 ) ) [cFlag] => [processNotifications] => [dateCreated] => 2015-12-08T13:59:19Z [createdBy] => User Name user@domain.com (email) [iFlag] => [eFlag] => 1 [_info] => Array ( [lastUpdated] => 2015-12-08T13:59:19Z [updatedBy] => User Name user@domain.com (email) ) ) )
Array ( [1] => Array ( [id] => 1535499 [tid] => 6970000 [text] => Hello. Lorem Ipsum. Lorem ipsum. [dFlag] => 1 [iFlag] => [rFlag] => [member] => [contact] => Array ( [id] => 187 [name] => User Name [_info] => Array ( [contact_href] => https://url/187 ) ) [cFlag] => [processNotifications] => [dateCreated] => 2015-12-08T13:59:19Z [createdBy] => User Name user@domain.com (email) [iFlag] => [eFlag] => 1 [_info] => Array ( [lastUpdated] => 2015-12-08T13:59:19Z [updatedBy] => User Name user@domain.com (email) ) ) ) 

您可以在数组美化器中看到它在哪里中断:http://phillihp.com/toolz/php-array-beautifier/

例如,某些字符串包含':)',因此当我应用 json_decode($response,true) 时,由于字符串中包含右括号,转换后的数组会中断。

我认为这是一个可能的解决方案的唯一方法是使用单独的函数(下面的示例)和正则表达式查询,但这似乎是开销。来源:http://php.net/manual/en/function.json-encode.php

<?php
function json_clean_decode($json, $assoc = false, $depth = 512, $options = 0) {
// sample regex
  $json = preg_replace("#(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|([\s\t]//.*)|(^//.*)#", '', $json);

  if(version_compare(phpversion(), '5.4.0', '>=')) {
        $json = json_decode($json, $assoc, $depth, $options);
  }
  elseif(version_compare(phpversion(), '5.3.0', '>=')) {
        $json = json_decode($json, $assoc, $depth);
  } else {
        $json = json_decode($json, $assoc);
  }

  return $json;
  }
?>

我想必须有另一种方法来处理从 json 解码的长字符串和特殊字符。

TIA

【问题讨论】:

  • JSON 没有任何 cmets,如果你有,它是一个自定义协议而不是真正的 JSON
  • 这只是一个示例函数。正则表达式可以更改为其他内容,即查找:)。我正在尝试寻找一种替代方法来处理这些字符串中的长字符串和括号。
  • 真正有效的 json 可以包含任意顺序的任意字符。如果现在有什么东西破坏了你的数组(我什至无法想象如何)它不是一个 json。
  • 你能不能先用add_slashes()到json,然后用json_decode?​​span>
  • 请注意,我们正在查看print_r 的输出。不要指望输出遵守某些语法!它不是 JSON。相同的 JSON 表示完全没有问题,所有字符串都将被引用,避免对括号的任何误解。如果这里有什么问题,那就是这个美化器,没有别的。

标签: php json regex string


【解决方案1】:

您提供的print_r 输出的解码 JSON 存在问题:密钥 iFlag 在同一对象中出现两次。这应该是不可能的。

您解码的原始 JSON 字符串如下所示:

$json = '[
    {
        "id": 1535497,
        "tid": 6970000,
        "text": "Hello :) error is back! It\'s quite annoying!",
        "dFlag": 1,
        "iFlag": null,
        "rFlag": null,
        "member": null,
        "contact": {
            "id": 187,
            "name": "User Name",
            "_info": {
                "contact_href": "https:\/\/url\/187"
            }
        },
        "iFlag": null,
        "cFlag": null,
        "processNotifications": null,
        "dateCreated": "2015-12-08T13:59:19Z",
        "createdBy": "User Name user@domain.com (email)",
        "eFlag": 1,
        "_info": {
            "lastUpdated": "2015-12-08T13:59:19Z",
            "updatedBy": "User Name user@domain.com (email)"
        }
    }
]';

确实,如果我像这样解码和打印它:

$data = json_decode($json, true); // translate objects to associative arrays
print_r ($data);

...输出与您在问题中提供的相同,除了重复的 iFlag 属性:

Array ( [0] => Array ( [id] => 1535497 [tid] => 6970000 [text] => Hello :) error is back! It's quite annoying! [dFlag] => 1 [iFlag] => [rFlag] => [member] => [contact] => Array ( [id] => 187 [name] => User Name [_info] => Array ( [contact_href] => https://url/187 ) ) [cFlag] => [processNotifications] => [dateCreated] => 2015-12-08T13:59:19Z [createdBy] => User Name user@domain.com (email) [eFlag] => 1 [_info] => Array ( [lastUpdated] => 2015-12-08T13:59:19Z [updatedBy] => User Name user@domain.com (email) ) ) )

数组美化器在此中断,仅表示此美化器不够好。它试图解释print_r 的输出,但显然它有一些弱点。然而,这并不表明 JSON 编码/解码存在问题。

print_r 实际上在“美化”输出本身方面做得很好,但在浏览器上下文中,您需要保留格式才能看到它,例如通过将该输出包装在pre 标签中。如果这样做,您将看到以下输出:

Array
(
    [0] => Array
        (
            [id] => 1535497
            [tid] => 6970000
            [text] => Hello :) error is back! It's quite annoying!
            [dFlag] => 1
            [iFlag] => 
            [rFlag] => 
            [member] => 
            [contact] => Array
                (
                    [id] => 187
                    [name] => User Name
                    [_info] => Array
                        (
                            [contact_href] => https://url/187
                        )

                )

            [cFlag] => 
            [processNotifications] => 
            [dateCreated] => 2015-12-08T13:59:19Z
            [createdBy] => User Name user@domain.com (email)
            [eFlag] => 1
            [_info] => Array
                (
                    [lastUpdated] => 2015-12-08T13:59:19Z
                    [updatedBy] => User Name user@domain.com (email)
                )

        )

)

现在我们可以再次对数据进行 JSON 编码:

$json = json_encode($data, JSON_PRETTY_PRINT);
echo $json;

输出是原始 JSON,除了重复的对象成员。没有其他问题:

[
    {
        "id": 1535497,
        "tid": 6970000,
        "text": "Hello :) error is back! It's quite annoying!",
        "dFlag": 1,
        "iFlag": null,
        "rFlag": null,
        "member": null,
        "contact": {
            "id": 187,
            "name": "User Name",
            "_info": {
                "contact_href": "https:\/\/url\/187"
            }
        },
        "cFlag": null,
        "processNotifications": null,
        "dateCreated": "2015-12-08T13:59:19Z",
        "createdBy": "User Name user@domain.com (email)",
        "eFlag": 1,
        "_info": {
            "lastUpdated": "2015-12-08T13:59:19Z",
            "updatedBy": "User Name user@domain.com (email)"
        }
    }
]

现在你可以再次解码:

$back = json_decode($json);
print_r ($back);

输出仍然是您提供的原始print_r 输出,但重复成员除外。所以 JSON 编码没有任何问题。

【讨论】:

  • 谢谢!我在发布之前修改了数组并打错了字。也许美化剂是误导性的。我会尝试 Pre 标签。再次感谢!
  • 问题出在美化器上。使用
     标签帮助我解决了这个问题。
猜你喜欢
  • 2012-10-06
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-28
  • 1970-01-01
相关资源
最近更新 更多