5

I am returning some data from DB using Eloquent and putting in in object of arrays. My response object to browser is displayed in this format:

// response()->json($response, 200);


[{
"id": 1,
"name": "car",
"make": ["bmw", "ford"]
"order": 1
},
{
"id": 2,
"name": "bike",
"make": ["aprilia"]
"order": 2
},
{
"id": 3,
"name": "boat",
"make": []
"order": 3
 },
(...)
]

Before returning it though, I wanted to filter it on server side. So I only return objects which do hold value in the "make" array.

So I am running this loop:

        foreach ($response as $key => $transport) {

            if (count($response[$key]['make']) == 0) {
                unset($response[$key]);
            };

        }

What php does is it converts the array to object and also adds keys to each inner object. So now my $response looks like:


// response()->json($response, 200);


{ // notice here it has changed from array to object
  "0": { // notice here it has added key "0"
    "id": 1,
    "name": "car",
    "make": ["bmw", "ford"]
    "order": 1
  },
    "1" : { // notice here it has added key "1"
    "id": 2,
    "name": "bike",
    "make": ["aprilia"]
    "order": 2
  },
 (...)
}

First of all - why? And second question - how to prevent/go back to array of objects response?

5
  • It is the same. Every array in PHP is by default has int keys. How do you convert the array back to object? Commented Apr 29, 2019 at 14:05
  • It is and it is not. When I pick this object from JS it will be treated as object of objects, so array methods wont be available (map, filter,etc ). The initial conversion from DB must be happening by the magic of Laravels collect() method. I tried to use toArray() methods provided by Laravel, but no joy. Commented Apr 29, 2019 at 14:06
  • 1
    I'm guessing you casting something wrong. Look here: 3v4l.org/ikRl4 for example Commented Apr 29, 2019 at 14:12
  • I think I figured it out, I just create another array and on the loop keep pushing non-empty objects to new array to finally return it. It is a walk-around but works. Commented Apr 29, 2019 at 14:13
  • To clarify, use array_values() because (array) will retain the nun sequential indexes. Commented Apr 29, 2019 at 14:37

1 Answer 1

6

When you unset a value from an indexed array in PHP, the existing indexes remain. Using a simple example with a small range of integers to illustrate, the following code unsets all odd integers from an array:

$numbers = range(1, 5); // [1, 2, 3, 4, 5];

foreach ($numbers as $index => $number) {
    if ($number % 2 !== 0) {
        unset($numbers[$index]);
    }
}

print_r($numbers);

Which yields:

Array
(
    [1] => 2
    [3] => 4
)

Note that the odd elements are removed, but the indexes of the existing elements are retained. Because of these gaps, the array isn't sequentially indexed at this point.

The consequence of this is, when you json_encode() this array, it assumes that these non-sequential indexes (let's just call them keys at this point) are to be retained, so it creates an object literal with keys instead. These keys are strings that just happen to be integers:

echo json_encode($numbers); // {"1":2,"3":4} 

Using array_values($numbers) will reset your array's indexes:

$reindexed = array_values($numbers);
echo json_encode($reindexed); // [2, 4]

Note: I mentioned in a comment that you can cast to an array using (array)—this is actually not correct as it will retain the non sequential indexes.

Hope this helps!

Sign up to request clarification or add additional context in comments.

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.