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
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
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) {
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.