【问题标题】:json_encode not preserving orderjson_encode 不保留顺序
【发布时间】:2014-01-21 15:28:37
【问题描述】:

我有一个多维数组,在 PHP 中:

Array
(
[1] => Array
    (
        [19] => Array
            (                    
                [type] => 2
            )            
        [6] => Array
            (                    
                [type] => 4
            )
        [12] => Array
            (                    
                [type] => 3
            )
    )

)

当我通过以下方式在 javascript 中对这个数组进行 json_encode:

 var jsonArray = <?php echo json_encode($above_array); ?>;

我明白了:

 Object
 (
 [1] => Object
 (
    [6] => Object
        (                    
            [type] => 2
        )
    [12] => Object
        (                    
            [type] => 4
        )
    [19] => Object
        (                    
            [type] => 3
        )
)

)

我想通过 id 保留第一个订单而不是第二个订单。

【问题讨论】:

  • 我如何保留第一个订单?
  • 使用其他东西作为键(例如key_1,key_2,key3),这样你就可以在解码json后进行排序
  • JSON 对象是无序的键值映射。 数组 是有序列表。任你选,Javascript/JSON 没有 ordered 映射。
  • 如果你想保留顺序,你需要一个数组,而不是一个对象。您需要生成一个如下所示的结构:[[19, {type: 2}], [9, { type: 2}], [6, {type: 4}], [12, {type: 3}]],即一个数组数组,其中每个嵌套数组包含两个元素,“索引”和type 对象。

标签: javascript php json


【解决方案1】:

问题是在 JavaScript 中只有数组是有序的,对象不是。

如果你有类似的东西:

array(
    array(
        'type' => 2
        'id' => 6
    ),
    array(
        'type' => 4
        'id' => 12
    ),
    array(
        'type' => 3
        'id' => 19
    )
)

然后在您的 JavaScript 中,您将拥有一个对象数组,并且该数组将保持其顺序。

它乱序的原因是因为你的数组的索引不是从 0 开始的,键没有按顺序排列并且键中有间隙。因此,在编码时,PHP 将其转换为对象而不是数组。

【讨论】:

    【解决方案2】:

    StackOverflow 上有一个问题 Does JavaScript Guarantee Object Property Order? 简而言之,答案是否定的,它没有。所以在将 PHP 数组转换为 Javascript 对象时,不会保留键顺序。

    PHP 和 Javascript 中数组的主要区别在于后者只能保存从零开始的连续整数键。因此,并非总是可以将 PHP 数组转换为 Javascript 数组。 我们来看几个例子:

    // 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
    
    1. 在第一个示例中,json_encode 将 PHP 数组转换为相同的 Javascript 数组。
    2. 在第二个示例中,它转换为对象,因为键顺序不是连续的。
    3. 在第三个示例中,它也转换为对象。但是在 Javascript 中,对象 2 和 3 将是相同的,具有相同的键顺序,即使键以不同的顺序列出。所以不是 json_encode 函数没有保留键顺序,而是 Javascript 本身。

    回到我们的问题:如何将 PHP 数组传递给 Javascript 并保留键顺序? 一种方法是将 PHP 键值对包装到数组中:

    // original array:
    array(
        3 => 'b', 
        0 => 'a'
    )
    
    // must be converted to:
    array(
        array(3, 'b'),
        array(0, 'a')
    )
    

    那么json_encode 将产生以下Javascript数组:

    [
      [3,"b"],
      [0,"a"]
    ]
    

    最后一部分是在 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
    

    这种方法也与非整数键兼容。

    这是在 PHP 端转换数组的代码(由 pr1001 在类似问题中建议)。它适用于一维数组。

    array_map(
        function($key, $value) { return array($key, $value); },
        array_keys($data),
        array_values($data)
    )
    

    下面是多维数组的递归函数实现:

    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)
        );
    }
    

    【讨论】:

    • 像魅力一样工作!
    【解决方案3】:

    要保持 PHP 数组的顺序,请使用 array_values() 函数。

    <?php $php_array = array_values($php_array); ?>
    var jsonArray = JSON.parse('<?php echo json_encode($php_array); ?>');
    

    【讨论】:

      猜你喜欢
      • 2014-12-01
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-08
      • 2012-12-15
      相关资源
      最近更新 更多