How to display json values that are in 2nd level o

2020-05-04 16:16发布

问题:

Having a problem on solving this code. These are the arrays

Array
(
    [0] => stdClass Object
        (
            [id] => 1
            [name] => delux
            [price] => 213
            [description] => 
            [tv] => 0
            [breakfast] => 0
            [park] => 0
            [wifi] => 0
            [ac] => 0
            [occupancy] => 
            [size] => 
            [view] => 
            [service] => 
            [terrace] => 0
            [pickup] => 0
            [internet] => 0
            [gym] => 0
            [note] => 
            [room_details] => {"img":["images/logo2.png","images/logo.png"]}
        )

    [1] => stdClass Object
        (
            [id] => 2
            [name] => hjghj
            [price] => 234
            [description] => 
            [tv] => 0
            [breakfast] => 0
            [park] => 0
            [wifi] => 0
            [ac] => 0
            [occupancy] => 
            [size] => 
            [view] => 
            [service] => 
            [terrace] => 0
            [pickup] => 0
            [internet] => 0
            [gym] => 0
            [note] => 
            [room_details] => 
        )

)

I want to echo the per images under room_details to show like this

images/logo2.png
images/logo.png

Here's my code

    foreach ($roomandsuits as $i => $item) { 

      $array_links = json_decode($item->room_details, true); { 

        foreach  ($array_links as $key => $value) {   

          foreach ($value as $content) { 

       echo $content; 

       }           
       }     
      } 
     }

Error in 3rd line and shows like this

images/logo2.png
images/logo.png

Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\resort\modules\mod_roomandsuits\tmpl\default.php on line 10 images/logo.png

回答1:

Try the below code. I added the details with comments.

foreach ($roomandsuits as $i => $item) { 

        if($item->room_details){  //check if value of $item->'room_details' not null

            $room_details = json_decode($item->room_details, true); //decode the json data

            if(!empty($room_details)){  //Check if room_details is not empty array
                $room = $room_details['img'];
                array_walk($room, function($value){  //using array_walk gate the value of room_details
                    echo $value .'<br/>';
                });

            }
        }

    }

DEMO



回答2:

You need to check you're working with an array before passing it to foreach.

The second element in $roomandsuits has an empty 'room_details'. Regardless, you're putting it through json_decode() and immediately passing to foreach.

$array_links = json_decode($item->room_details, true); // there was a misplaced opening brace here previously...

if (!is_array($array_links)) {
    continue;
}

foreach ($array_links as $key => $value) {   


回答3:

Your deep json strings are structurally different. Decoding the first generates an img keyed array containing two strings. The second has is null or an empty string (your post doesn't reveal that for us). Your final foreach() is trying to iterate a non-iterable data type -- this is the cause of your issue.


I might suggest a refactor to avoid so many foreach() structures...

You can isolate the room_details column with array_column() after casting the input array as an array.

It is important that you not only check that the subarray is not empty, but that it actually contains the img key. If it does, my script will assume that it is an indexed array.

Then iterate the collection of json strings, decode them, then unpack (with the splat operator ...) and push them into your result array.

When finished building the result array, implode the elements with <br>.

Code: (Demo)

$array = [
    (object)[
        'id' => 1,
        'name' => 'delux',
        'room_details' => '{"img":["images/logo2.png","images/logo.png"]}'
    ],
    (object)[
        'id' => 2,
        'name' => 'hjghj',
        'room_details' => ''
    ]
];

$images = [];
foreach (array_column((array)$array, 'room_details') as $json) {
    $obj = json_decode($json);
    if (isset($obj->img)) {
        array_push($images, ...$obj->img);
    }
}

echo implode("\n", $images);  // implode with <br> for html linebreaks

Output:

images/logo2.png
images/logo.png

One advantage of using array_column() is if room_details does not exist for some reason in one of the objects, it will be omitted from the looping process. This avoids the need to check if room_details isset() before trying to decode it.



标签: php arrays json