1

I have a big JSON that looks something like this:

{
    "bracers": [
        {
            "id": "Bracers_208",
            "name": "Unearthed Boon"
        }
    ],
    "offHand": [
        {
            "id": "Bracers_208",
            "name": "Unearthed Boon"
        },
        {
            "id": "Weapon123",
            "name": "Some Weapon Boon"
        },
        {
            "id": "Weapon456",
            "name": "Some Other Weapon Boon"
        }
    ],
    "mainHand": [
        {
            "id": "Weapon123",
            "name": "Some Weapon Boon"
        }
    ]
}

I decode the JSON like this:

$itemDB = json_decode($json, true);

What I want to do now is to remove all entries from offHand that are already in mainHand. So I loop through both, compare the id and unset() the value if there's a match.

foreach($itemDB['offHand'] as $index => $item) {

    foreach($itemDB['mainHand'] as $key => $weapon) {

        if($item['id'] == $weapon['id']) {

            unset($itemDB['offHand'][$index]);

        }

    }

}

Then I encode it again:

$newJSON = json_encode($itemDB, JSON_PRETTY_PRINT);

The removal of duplicates works, but the offHand array is changed into an object (or assoc array) that looks like this:

{
    "bracers": [
        {
            "id": "Bracers_208",
            "name": "Unearthed Boon"
        }
    ],
    "offHand": [
        "0": {
            "id": "Bracers_208",
            "name": "Unearthed Boon"
        },
        "2": {
            "id": "Weapon456",
            "name": "Some Other Weapon Boon"
        }
    ],
    "mainHand": [
        {
            "id": "Weapon123",
            "name": "Some Weapon Boon"
        }
    ]
}

Why does this happen and how can I prevent it?

Edit: Just to clarify, if I remove the unset function and just do nothing inside that loops ( or just add a property to the objects), the numbered additional keys in the JSON aren't there and the JSON array is fine. That's why I concluded that unset is causing this.

8
  • PHP won't loop over JSON (which is just a string representing structured data like arrays or objects), only over arrays, so you must be converting your JSON to an array to be able to loop over it in the first place Commented Mar 29, 2015 at 11:23
  • of course I json_decode it before. I edited to clarify. Commented Mar 29, 2015 at 11:29
  • Well then if you var_dumped the array after json_decoding it, then you'd see that those "additional keys" already exist Commented Mar 29, 2015 at 11:33
  • 1
    An interesting effect, indeed. I learned not to unset() inside an array I currently loop over. Actually not that surprising, that such thing causes problems... Commented Mar 29, 2015 at 11:33
  • please consider commenting on the downvote so I can improve my question :-/ Commented Mar 29, 2015 at 11:45

2 Answers 2

2

After you're loop ends, add the following line of code to remove the keys from the offHand array element:

$itemDB['offHand'] = array_values($itemDB['offHand']);
Sign up to request clarification or add additional context in comments.

5 Comments

Whilst this might be a workaround it does not answer the question which was "why"...
And that will magically create a PHP array of values without keys?
@MarkBaker the issue is not the existence of keys, no array comes without, but whether the keys are of numerical type or strings. That far this suggestion is correct... Apart from that it is a really crude attempt to afterwards fix something broken into something usable, which rarely is a good idea.
Incredibly, it works.... it appears to be json_encode() that's broken in some way, or simply can't handle non-contiguous keys.... wonder if the new json handling with PHP7 will fix the problem
it did work and here is a more complete answer as to why: stackoverflow.com/a/20373067/1523417
0

As much a I think , by unset, you are removing a part of array, making it non sequential Thus it might be converted into object

I guess the above line was bit unclear, so consider this example,

function ep($f)
{
    echo "<br><pre><code>";
    print_r($f);
    echo "</code></pre><br";
}
$t = array("a","b","c");

ep(json_encode($t));

unset($t[1]);

ep(json_encode($t));

Forget the function ep.On line 1 , we declare a sequential array and print it, as it is sequential it prints as an array. On line 2, we break the sequence. So printing it again , though it is an array, (*it maybe PHP's function does not know how to convert it) it printed as Object

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.