当对象键是数字的、连续的并且从0开始时,axios为什么要将JSON对象转换为数组



这是我的axios请求

axios({
method: 'put',
url: url,
data: data
}).then(function (response) {
console.log(response.data)
})
.catch(function (error) {
console.log(error)
})

它是由一个vue组件(一个表组件(组成的,用于提交表单数据。

然后,我为data尝试了以下JSON对象

"building": {
"a": ['Level 1', 0.0, 0, '', '', true],
"b": ['Level 2', 3.8, 40, '', '', false],
"c": ['Level 3', 7.6, 50, '', '', false],
"d": ['Level 4', 11.4, 50, '', '', false]
} // keys not numeric
"building": {
"1": ['Level 1', 0.0, 0, '', '', true],
"2": ['Level 2', 3.8, 40, '', '', false],
"3": ['Level 3', 7.6, 50, '', '', false],
"4": ['Level 4', 11.4, 50, '', '', false]
} // keys don't start at 0
"building": {
"0": ['Level 1', 0.0, 0, '', '', true],
"2": ['Level 2', 3.8, 40, '', '', false],
"3": ['Level 3', 7.6, 50, '', '', false],
"4": ['Level 4', 11.4, 50, '', '', false]
} // keys not consecutive
"building": {
"0": ['Level 1', 0.0, 0, '', '', true],
"1": ['Level 2', 3.8, 40, '', '', false],
"2": ['Level 3', 7.6, 50, '', '', false],
"3": ['Level 4', 11.4, 50, '', '', false]
} // keys are numeric, consecutive, start at 0

当我收到前3个时,它们都保留为对象,但第4个(数字,连续,从0开始(转换为数组。

我该如何阻止这种情况的发生?

澄清

  • 我希望我接收的数据是一个对象
  • PHP 8是接收put请求的后端,然后将数据直接作为响应发送回
  • 我在发送axios请求之前执行console.log(data),这是所有4的对象。那么console.log(response.data)是用于前3个的对象,并且是用于后3个的数组

您的问题是PHP不能区分数组和对象。在转换为JSON和从JSON转换时,它使用一条规则来确定关联数组应该转换为JSON数组还是JSON对象。如果键是从0开始的顺序数字键,它会将其转换为JSON数组。否则,它会将其转换为对象。键是字符串还是数字显然无关紧要。

解决方案是不转换到关联数组和从关联数组转换,而是让json_decode()生成stdClass对象和数组的混合。这使它能够跟踪什么是对象或不是对象。要做到这一点,要么在解码时不传递第二个参数,要么传递显式false:

// this variable will probably be of type stdClass
$decoded = json_decode($input, false);

在PHP中处理stdClass对象时,必须稍微详细一点。您将使用类似property_exists()的方法(而不是array_key_exists()isset()(,并且要进行迭代,您需要首先转换为array,例如:

foreach ((array)$decoded as $key => $value) {
}

如果不能控制服务器上的JSON解码,您可能需要考虑更改数据模型,使其不具有数字键,或者在客户端编写代码,以处理JSON中有时出现的数组(当需要对象时(。这很烦人,但这是PHP很久以前做出的决定,我们只需要处理它

最新更新