为什么axios将JSON对象转换为数组,当对象key是数字,连续的,从0开始的时候?
Why does axios convert JSON objects to arrays when the object keys are numerical, consecutive, and start at 0?
这是我的 axios 请求
axios({
method: 'put',
url: url,
data: data
}).then(function (response) {
console.log(response.data)
})
.catch(function (error) {
console.log(error)
})
它是由一个 vue 组件制成的,用于提交表单数据(一个 table 组件)。
然后我为 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 个的对象和最后一个的数组。
你的问题是PHP不区分数组和对象。当与 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 很久以前做出的决定,我们必须处理它。
这是我的 axios 请求
axios({
method: 'put',
url: url,
data: data
}).then(function (response) {
console.log(response.data)
})
.catch(function (error) {
console.log(error)
})
它是由一个 vue 组件制成的,用于提交表单数据(一个 table 组件)。
然后我为 data
"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 个的对象和最后一个的数组。
你的问题是PHP不区分数组和对象。当与 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 很久以前做出的决定,我们必须处理它。