json_encode不保留顺序 [英] json_encode not preserving order
问题描述
我在PHP中有一个多维数组:
I have a multi dimensional array, in PHP:
Array
(
[1] => Array
(
[19] => Array
(
[type] => 2
)
[6] => Array
(
[type] => 4
)
[12] => Array
(
[type] => 3
)
)
)
当我json_encode这个数组在javascript中通过:
When i json_encode this array in javascript via:
var jsonArray = <?php echo json_encode($above_array); ?>;
我得到:
Object
(
[1] => Object
(
[6] => Object
(
[type] => 2
)
[12] => Object
(
[type] => 4
)
[19] => Object
(
[type] => 3
)
)
)
我想保留第一个订单而不是第二个订单。
I want to preserve the first order and not the second one by id.
推荐答案
StackOverflow上有一个问题
JavaScript保证对象物业订单?
简而言之,答案是否定的,但事实并非如此。因此,当将PHP数组转换为Javascript对象时,不会保留键顺序。
There's a question on StackOverflow Does JavaScript Guarantee Object Property Order? In short, the answer is no, it doesn't. So when converting a PHP array to a Javascript object, the key order will not be preserved.
PHP和Javascript中的数组之间的主要区别在于后者只能保存从零开始的顺序整数键。因此,并不总是可以将PHP数组转换为Javascript数组。
让我们看几个例子:
The major difference between arrays in PHP and Javascript is that the latter can hold only sequential integer keys starting from zero. So it's not always possible to convert a PHP array to a Javascript array. Let's look at a few examples:
// example 1
echo json_encode(array(0 => 'a', 1 => 'b')) // outputs ["a","b"]
// example 2
echo json_encode(array(0 => 'a', 3 => 'b')) // outputs {"0":"a","3":"b"}
// example 3
echo json_encode(array(3 => 'b', 0 => 'a')) // outputs {"3":"b","0":"a"}, but in Javascript the key order will be the same as in example 2
- 在第一个示例中,
json_encode
将PHP数组转换为相同的Javascript数组。 - 在第二个例子中,它转换为一个对象,因为键顺序不是顺序的。
- 在第三个例子中,它也转换为一个东西。但是在Javascript中,对象2和3将是相同的,具有相同的键顺序,即使键以不同的顺序列出。所以它不是
json_encode
不保留键顺序的函数,而是Javascript本身。
- In the first example,
json_encode
converts a PHP array into an identical Javascript array. - In the second example, it converts to an object, because the keys order is not sequential.
- In the third example, it also converts to an object. But in Javascript, the objects 2 and 3 will be the same, with the same key order, even though the keys are listed in a different order. So it's not
json_encode
function that is not preserving the key order, but Javascript itself.
回到我们的问题:如何将PHP数组传递给Javascript,保留关键顺序?
一种方法是将PHP键值对包装到数组中:
Returning to our question: how to pass a PHP array to Javascript preserving the key order? One approach is to wrap PHP key-value pairs into arrays:
// original array:
array(
3 => 'b',
0 => 'a'
)
// must be converted to:
array(
array(3, 'b'),
array(0, 'a')
)
然后 json_encode
将导致以下Javascript数组:
Then json_encode
will result in the following Javascript array:
[
[3,"b"],
[0,"a"]
]
最后一部分是在Javascript中迭代这样一个数组:
And the last part is iterating through such an array in Javascript:
var php_encoded_array = [
[3,"b"],
[0,"a"]
];
for (var i=0; i < php_encoded_array.length; i++) {
var rec = php_encoded_array[i],
key = rec[0],
value = rec[1];
console.log(key + ': ' + value);
}
// It will output:
// 3: b
// 0: a
// Which is the exact same order as in the PHP array
此方法也与非整数键兼容。
This approach is also compatible with non-integer keys.
以下是在PHP端转换数组的代码(在类似问题中由 pr1001 建议)。它适用于一维数组。
Here's the code (suggested by pr1001 in a similar question) for converting an array on the PHP side. It will work for one-dimensional arrays.
array_map(
function($key, $value) { return array($key, $value); },
array_keys($data),
array_values($data)
)
这里是多维数组的递归函数实现:
And here's a recursive function implementation for multi-dimensional arrays:
function array_preserve_js_order(array $data) {
return array_map(
function($key, $value) {
if (is_array($value)) {
$value = array_preserve_js_order($value);
}
return array($key, $value);
},
array_keys($data),
array_values($data)
);
}
这篇关于json_encode不保留顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!