我有一个到服务器的 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));
答案 0 :(得分: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"
}
答案 1 :(得分: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 documented 的 NULL
返回值可以(但不能)表示解析 JSON 文本时出错。
这里是 PHP 手册的摘录:
<块引用>返回值
以适当的 PHP 类型返回以 json [引用第一个参数] 编码的值。值 true
、false
和 null
分别作为 true
、false
和 null
返回。 null
如果 json [对第一个参数的引用] 无法解码或编码数据比嵌套限制更深,则返回。 [我强调]
由于 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 对象表示法 (JSON) 数据交换格式中。
现在这是给老板留下深刻印象的声明!
既然这个答案已经不通了,接下来就是:如何处理?好吧,检查返回类型和错误函数 或 - 现在推荐 - 使用适当的标志调用 json_decode() 以抛出错误:
$result = json_decode($jsonData, true, 512, JSON_THROW_ON_ERROR);
这突出了解码、字符编码和限制命中等直接可见并委托给标准错误处理程序,以便您可以自上而下地编写代码。
很好,感谢所有的鱼,一切都很好,花花公子,但是,现在我知道有一个错误,但不工作的情况还是和之前一样,那为什么snap 是无效的 JSON?
如果这仍然让您感到困惑,或者这可能是前面的第一个问题(而不是问题中所写的 PHP 或 json_decode
),那么答案就更简单了:您需要使用一种工具来告诉您为什么 JSON 已损坏。
这可以是语法高亮,但更有可能是您希望验证器显示实际错误。
例如在 IDE 中(此处为 PhpStorm):
$jsonData = /** @lang JSON */ '{
"data": {
...
答案再次是语法错误,这里提示
<块引用>JSON 标准不允许尾随逗号
现在还有什么好说的?如果您看到 json_decode 错误并且您看不到 JSON 已损坏,请先验证它。仅通过查看 JSON 文本就很容易错过 JSON 编码错误。而且往往不值得。无效的 JSON?算了吧。大功告成。
激活 JSON_THROW_ON_ERROR
,您的代码就可以保持不变,现在包含电池。