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

Why PHP json_decode can't parse this JSON

我有一个对服务器的 cURL 请求,它 return 是这种 jsonp 类型的数据,但我不知道为什么 PHP json_decode return 什么都没有正在解析此 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 中的 returns。这是我的代码看看并告诉我这里发生了什么?为什么 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));

这些都无效 JSON。你总是可以 运行 你的 JSON 通过像 JSON Lint 这样的 lint 来确保它是有效的。

你的小例子在第 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"
}

Why PHP json_decode can't parse this 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));

this is my code look and tell me what is happening here? Why PHP can't parse this?

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

首先是您示例中 json_decode return 的基础知识:NULL.

有趣!

为什么这个 NULL return 值很有趣?

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

其次,来自 json_decode() is documentedNULL return 值表示它可以(但不能)发出解析 JSON 文本的错误信号。

此处摘自 PHP 手册:

Return Values

Returns the value encoded in json [reference to the first parameter] in appropriate PHP type. Values true, false and null are returned as true, false and null respectively. null is returned if the json [reference to the first parameter] cannot be decoded or if the encoded data is deeper than the nesting limit. [highlight by me]

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

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

问题多于问题,如何了解更多?

在您的情况下,您可以使用 json_last_error() and json_last_error_msg() 函数找到它。因此,让我们看看有问题的代码,这些功能是什么 return:int(4) 用于错误代码,string(12) "Syntax error" 用于错误消息。

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

让我们换个说法:

Why PHP json_decode can't parse this JSON

因为 JSON 有语法错误。


好的,这现在看起来简单得有点尴尬,对吧?但是等等,对于 PHP 的 json_decode(),什么是 JSON?好吧,再次查看手册是强制性的:

PHP implements a superset of JSON as specified in the original » RFC 7159.

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


因为 JSON 文本不在 RFC 7159 JavaScript 对象表示法 (JSON) 数据交换格式中。


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

好吧,既然这个答案已经过时了,那么下一个问题是:如何处理?那么,检查 return 类型和错误函数 - 现在推荐 - 使用适当的标志调用 json_decode() 以抛出错误:

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

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


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

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

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

例如在 IDE(这里是 PhpStorm)中:

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

答案又是语法错误,这里提示

JSON standard does not allow trailing comma

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

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