【问题标题】:Why PHP json_decode can't parse this JSON为什么 PHP json_decode 无法解析这个 JSON
【发布时间】:2021-09-04 03:13:37
【问题描述】:

我有一个对服务器的 cURL 请求,它返回这个 jsonp 类型的数据,但我不知道为什么 PHP json_decode 在解析这个 JSON 文本时什么都不返回。 这是我收到的请求:

{
  "data": {
    "name": "Color Collections",
    "category": "collection",
    "palettes": [
      {
        "name": "America's Colors",
        "category": "collection",
        "colors": [
          {
            "number": "AC-1",
            "name": "Coastal Fog",
            "family": "Neutral",
            "url": "http://www.benjaminmoore.com/en-us/paint-color/ac-1?apiKey=9471009bd36bd062c688",
            "shortURL": "/ac-1",
            "hex": "CAC4B0",
            "r": 202,
            "g": 196,
            "b": 176,
            "exteriorAvailability": "available",
            "wetSampleSKU": null,
            "drySampleSKU": null,
            "eStoreAvailable": false,
            "productTypesAvailable": "paint",
            "stainOpacitiesAvailable": null
          },
          
        ],
        "colorList": [
          "AC-1",
          "AC-2",
          "AC-3",
          "AC-4",
          "AC-5",
          "AC-6",
          "AC-7",
          "AC-8",
          "AC-9",
          "AC-10",
          "AC-11",
          "AC-12",
          "AC-13",
          "AC-14",
          "AC-15",
          "AC-16",
          "AC-17",
          "AC-18",
          "AC-19",
          "AC-20",
          "AC-21",
          "AC-22",
          "AC-23",
          "AC-24",
          "AC-25",
          "AC-26",
          "AC-27",
          "AC-28",
          "AC-29",
          "AC-30",
          "AC-31",
          "AC-32",
          "AC-33",
          "AC-34",
          "AC-35",
          "AC-36",
          "AC-37",
          "AC-38",
          "AC-39",
          "AC-40",
          "AC-41",
          "AC-42"
        ],
        "code": "AC",
        "description": "42 soft hues inspired by the pale gray of our beautiful coastlines to the rich earth tones of our Southwestern deserts. ",
        "url": "http://www.benjaminmoore.com/en-us/for-your-home/color-gallery?apiKey=9471009bd36bd062c688#&ce_vm=2&ce_col=AC?apiKey=9471009bd36bd062c688",
        "rows": 7,
        "totalColors": 42,
        "eStoreProductCode": null
      },
    ]
  },
  "error": "",
  "countryCode": "en-us",
  "brand": "BenjaminMoore,Corotech,Coronado,Inslx,Lenmar,Maxum"
}

但即使我删除了一些部分以使其工作如此短,但 PHP json_decode 仍然没有返回任何内容。这是我的代码外观并告诉我这里发生了什么?为什么 PHP 不能解析这个?

 $jsonData = '{
    "data": {
      "name": "Color Collections",
      "category": "collection",
    },
    "error": "",
    "countryCode": "en-us",
    "brand": "BenjaminMoore,Corotech,Coronado,Inslx,Lenmar,Maxum"
  }';
  print_r( json_decode($jsonData, true));

【问题讨论】:

  • 首先转义单引号 "name": "America's Colors" **** 其次删除右花括号中多余的逗号。 “stainOpacitiesAvailable”:null },和“eStoreProductCode”:null },

标签: php json parsing request


【解决方案1】:

为什么 PHP json_decode 无法解析这个 JSON

 $jsonData = '{
    "data": {
      "name": "Color Collections",
      "category": "collection",
    },
    "error": "",
    "countryCode": "en-us",
    "brand": "BenjaminMoore,Corotech,Coronado,Inslx,Lenmar,Maxum"
  }';
  print_r( json_decode($jsonData, true));

这是我的代码外观并告诉我这里发生了什么?为什么 PHP 不能解析这个?

PHP 可以很好地解析这个 PHP 代码。而json_decode也做了标准的操作,让我们看看这是怎么回事。

首先是关于json_decode 在您的示例中返回的基础知识:NULL

有趣!

为什么这个NULL返回值很有趣?

首先,乍一看很明显,它不是解码后的字符串中的 JSON 文本,或者是吗?

其次,来自json_decode() is documentedNULL 返回值可以(但不能)表示解析 JSON 文本时出错。

这里是 PHP 手册的摘录:

返回值

以适当的 PHP 类型返回以 json [引用第一个参数] 编码的值。值 truefalsenull 分别返回为 truefalsenull如果无法解码 json [对第一个参数的引用] 或编码数据深度超过嵌套限制,则返回 null [highlight by me]

由于 JSON 文本不是“null”,将NULL 视为返回类型表明已经存在问题:

也许json_decode 检测到无效输入并拒绝对其进行操作?或者它是否达到了嵌套限制(depth,第三个参数)?还是字符串不是 UTF-8 编码的?

疑问大于疑问,如何了解更多?

在您的情况下,您可以使用 json_last_error()json_last_error_msg() 函数找到它。因此,让我们看看这些函数返回的问题代码:int(4) 为错误代码,string(12) "Syntax error" 为错误消息。

哦,传递给json_decode() 的 JSON 文本中存在语法错误。这意味着不是嵌套限制或字符编码问题!

我们换个说法:

为什么 PHP json_decode 无法解析这个 JSON

因为 JSON 有语法错误。


好的,现在看起来可能很简单,对吧?但是,等等,对于 PHP 的json_decode(),什么是 JSON?好吧,必须再次查看手册:

PHP 实现了原始 »RFC 7159 中指定的 JSON 超集。

所以(更多)正确答案是:


因为 JSON 文本不是 RFC 7159 JavaScript Object Notation (JSON) 数据交换格式。


现在这是给老板留下深刻印象的声明!

好吧,既然这个答案已经不在了,接下来就是:如何处理它?好吧,检查返回类型和错误函数 - 现在推荐 - 使用适当的标志调用 json_decode() 以引发错误:

$result = json_decode($jsonData, true, 512, JSON_THROW_ON_ERROR);

这会突出显示直接可见的解码、字符编码和限制命中等,并委托给标准错误处理程序,以便您可以自上而下编写代码。


很好,感谢所有的鱼,一切都很好,花花公子,但是,现在我知道有一个错误,但仍然 不起作用的情况和之前一样,所以为什么快照是不是有效的 JSON?

如果这仍然让您感到困惑,或者可能是前面的第一个问题(而不是问题中所写的 PHP 或 json_decode),那么答案就更简单了:您需要使用一个工具来告诉您 为什么 JSON 坏了。

这可以是语法高亮,但您更可能希望验证器显示实际错误。

例如在 IDE(此处为 PhpStorm)中:

  1. 将字符串的内容标记为 JSON,例如使用 PHPDoc:
    $jsonData = /** @lang JSON */ '{
        "data": {
        ...
    
  2. 在 IDE 突出显示的 JSON 文本字符串中找到任何错误(取决于您使用的产品,这可能会有所不同): 这里是红色波浪下划线
  3. 激活它的错误信息以获得更多信息(例如用鼠标悬停它并等待工具提示出现):

再一次,答案是语法错误,这里提示

JSON 标准不允许尾随逗号

现在还有什么要说的?如果您看到 json_decode 错误并且您看不到 JSON 已损坏,请先验证它。仅通过查看 JSON 文本就很容易错过 JSON 编码错误。而且往往不值得。无效的 JSON?算了吧。完成了。

激活JSON_THROW_ON_ERROR,您的代码可以保持不变,现在包含电池。

【讨论】:

    【解决方案2】:

    这些都不是有效的 JSON。您始终可以通过 JSON Lint 之类的 lint 运行您的 JSON,以确保它有效。

    你的小例子在第 4 行有一个额外的逗号:

      {
        "data": {
          "name": "Color Collections",
          "category": "collection", //<-------------here
        },
        "error": "",
        "countryCode": "en-us",
        "brand": "BenjaminMoore,Corotech,Coronado,Inslx,Lenmar,Maxum"
      }
    

    你更大的在第 24 行有一个额外的逗号。

    {
      "data": {
        "name": "Color Collections",
        "category": "collection",
        "palettes": [
          {
            "name": "America's Colors",
            "category": "collection",
            "colors": [
              {
                "number": "AC-1",
                "name": "Coastal Fog",
                "family": "Neutral",
                "url": "http://www.benjaminmoore.com/en-us/paint-color/ac-1?apiKey=9471009bd36bd062c688",
                "shortURL": "/ac-1",
                "hex": "CAC4B0",
                "r": 202,
                "g": 196,
                "b": 176,
                "exteriorAvailability": "available",
                "wetSampleSKU": null,
                "drySampleSKU": null,
                "eStoreAvailable": false,
                "productTypesAvailable": "paint",
                "stainOpacitiesAvailable": null
              }, //<------------------------------------- here
              
            ],
            "colorList": [
              "AC-1",
              "AC-2",
              "AC-3",
              "AC-4",
              "AC-5",
              "AC-6",
              "AC-7",
              "AC-8",
              "AC-9",
              "AC-10",
              "AC-11",
              "AC-12",
              "AC-13",
              "AC-14",
              "AC-15",
              "AC-16",
              "AC-17",
              "AC-18",
              "AC-19",
              "AC-20",
              "AC-21",
              "AC-22",
              "AC-23",
              "AC-24",
              "AC-25",
              "AC-26",
              "AC-27",
              "AC-28",
              "AC-29",
              "AC-30",
              "AC-31",
              "AC-32",
              "AC-33",
              "AC-34",
              "AC-35",
              "AC-36",
              "AC-37",
              "AC-38",
              "AC-39",
              "AC-40",
              "AC-41",
              "AC-42"
            ],
            "code": "AC",
            "description": "42 soft hues inspired by the pale gray of our beautiful coastlines to the rich earth tones of our Southwestern deserts. ",
            "url": "http://www.benjaminmoore.com/en-us/for-your-home/color-gallery?apiKey=9471009bd36bd062c688#&ce_vm=2&ce_col=AC?apiKey=9471009bd36bd062c688",
            "rows": 7,
            "totalColors": 42,
            "eStoreProductCode": null
          },
        ]
      },
      "error": "",
      "countryCode": "en-us",
      "brand": "BenjaminMoore,Corotech,Coronado,Inslx,Lenmar,Maxum"
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 2017-02-04
      • 1970-01-01
      相关资源
      最近更新 更多