How to Preserve Object Order from PHP to Javascript

In PHP we use an array as both a vector and a hashmap (or dict). This is because it’s implemented internally as an ordered hashmap. So order is preserved. This works the same way in Objects as well. However, in Javascript this is not the case. In Javascript arrays preserve order, but objects do not. So when transferring data structures between your PHP and Javascript using JSON notation you might run into issues like this where you care about the order of elements in the object.

<?php
$arr = [
    4 => "I'm first",
    1 => "I'm second",
    3 => "I'm third"
];

echo json_encode($arr, JSON_PRETTY_PRINT);

This should give you something like the following.

{
    "4": "I'm first",
    "1": "I'm second",
    "3": "I'm third"
}

Now let’s say you traverse this object in your Javascript (it becomes an object in Javascript because arrays do not have keys in JS, but they do in PHP) and you might expect the order of the elements to be the same. Though this is not necessarily the case. You might get the same order, or you might not.

var obj = {"4":"I'm first","1":"I'm second","3":"I'm third"};

var s = "";
for(var x in obj) {
    s = + obj[x] + "\n";
}

console.log(s);

You could get output like the following.

I'm second
I'm third
I'm first

Whereas in PHP you always get the following output consistently.

I'm first
I'm second
I'm third

So how do we fix this problem? Well, since arrays in Javascript preserve order just fine, and objects do not, we could simply create an array of objects to ensure the right order. So the following code in PHP should do it.

<?php
$json = [];
foreach($arr as $key => $value) {
    $json[] = [$key => $value];
}

echo json_encode($json, JSON_PRETTY_PRINT);

Now, we get something like this.

[
    {
        "4": "I'm first"
    },
    {
        "1": "I'm second"
    },
    {
        "3": "I'm third"
    }
]

When you traverse this array in Javascript you get the correct order every time.

for(var x in obj) {
    for(var n in obj[x]) {
        obj[x][n]; // now you can both maintain order and have access to the key
    }
}