PHP function return multiple JSON object - php

I have a php function that currently looks like this
function renderJson(PageArray $items) {
$myData = array();
$myData['title'] = [];
$myData['url'] = [];
// cycle through all the items
foreach($items as $item) {
array_push($myData["title"],$item->title);
array_push($myData["url"],$item->url);
}
return json_encode($myData);
}
It currently works in this shape as output
{"title":["A","B"],"url":["A","B"]}
But this is what I am trying to achieve
{"title":["A"],"url":["A"]},{"title":["B"],"url":["B"]}
I am trying to return it as a JSON encode.The $item->title and $item->url returns a string.Any help would be great.

So now you get this :
{"title":["A","B"],"url":["A","B"]}
But you want this :
{"title":["A"],"url":["A"]},{"title":["B"],"url":["B"]}
What you want is add a new "item" each time you loop and each item have a title and an url. Right now you return an array that contain 2 sub-array : one for the title, one for the url.
Try this way :
function renderJson(PageArray $items) {
// Your result array
$myData = array();
// cycle through all the items
foreach($items as $item) {
// Each time you loop, you add a new array in your main array with a title and an URL
$myData[] = array(
"title" => $item->title,
"url" => $item->url
);
}
return json_encode($myData);
}
I used [] because he does what you need : push element at the end of your main array. It's the short way to use array_push(). Here is the documentation for more details : http://php.net/manual/en/function.array-push.php
The output will be :
[{"title":["A"],"url":["A"]},{"title":["B"],"url":["B"]}]

What you want to return is not, of course, valid json. At this point return an array containing those two objects (i.e., push the whole $item to $myData)
function renderJson(PageArray $items) {
$myData = array();
// cycle through all the items
foreach($items as $item) {
array_push($myData,['title' => $item->title, 'url' => $item->url]);
}
return json_encode($myData);
}
which gives you something in the form of
[{"title":"A","url":"A"},{"title":"B","url":"B"}]

You create invalid JSON by concatenation your JSON by comma. Either get your client (speak receiver of the json data) to split the result by comma and then parsing each JSON by its own.
Otherwise you could create a "big" JSON string, containing both (or all if there are more) of your JSON data.
Just create an array in PHP, add a new element for each JSON data, then json_encode() it and go over it by a loop in your client.
What you will use in the end, doesnt really matter that much, but I would use the second approach by a lot over the first, since it´s much cleaner.

Related

Array of String values, not an array of object Strings

Basically I am calling an API to get an array of URLs for an image.
I start off by doing this
$mainResponse = array(
"result" => array(
),
"ack" => "success"
);
I will then make my call and add the image URLs like this:
foreach($resp->Item as $item) {
$picture = $item->PictureURL;
array_push($mainResponse['result'], $picture);
}
Finally, I will echo this out to me.
echo json_encode($mainResponse);
The problem I am facing is that my response is
{"result":[{"0":"IMAGE_URL","1":"IMAGE_URL"}],"ack":"success"}
Where I would want it to be like....
{"result":["IMAGE_URL","IMAGE_URL"],"ack":"success"}
Where did I go wrong in my PHP code?
Seems like $picture is a associative array, change the foreach loop with this:
foreach($resp->Item->PictureURL as $item) {
foreach($item as $_item){
array_push($mainResponse['result'],$_item);}
}
For some reason this API returns an object instead of an array.
You can just do:
foreach ($resp->Item as $item) {
$picture = $item->PictureURL;
array_merge($mainResponse['result'], (array)$picture);
}
You can use array_push if you want every item to have separate pictures.

Using ng-repeat to loop through an array that is formatted like a string

I have recently started adding Angular to an old app I made. Part of the app stores a json encoded array in a single cell in a mySql table. I know this is frowned upon, but I'm 100% sure it won't come back to bite me later. In the past I've just been able to do a json_decode on the array and output the values in an ordered list. Since I've included Angular, the data is being encoded and echoed at the end of the php file. It is then picked up by the Angular code and I'm able to loop through this deeply nested multidimensional object until it gets to this part...
"sub_items":"[\"subOne\",\"subTwo\",\"subThree\"]"
The closest I can get is to output the string including all the backslashes, brackets and quotes which makes sense because it is a string.
I've tried doing a json_decode on every instance of sub_items, but it's not working. I think that's because the whole thing just gets encoded again.
How might I be able to loop through this array?
EDIT
I have made some progress with the following based on comments in the answer from #Yaser Adel Mehraban.
foreach($master as $index => $item) {
if($category == $item['category']) {
$sub = [];
$sub['sub_items'] = json_decode($item['sub_items']);
unset($item['sub_items']);
array_push($items, $item, $sub);
}
}
This returns
...created_at":"2016-11-01 14:19:07"},{"sub_items":["subOne","subTwo","subThree"...
The formatting of the array I was having trouble with is correct now I think, but it's sitting outside the item. I have tried to array_merge as well, but it adds a new key which would force an unnecessary ng-repeat to step down I think. Suggestions...
UPDATED:
You should decode using array options and then iterate through them using ng-repeat, however to get decode working you first need to split your string and get the second part:
$subItemsStr = explode('"sub_items":"[\"subOne\",\"subTwo\",\"subThree\"]"')[1];
$subItems = json_decode($subItemsStr, true);
Then you can use it.
Try this :
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl',function($scope) {
var jsonObj = {
"sub_items":"[\"subOne\",\"subTwo\",\"subThree\"]"
}
var jsonString = jsonObj.sub_items;
$scope.items = JSON.parse(jsonString);
});
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="item in items">
{{item}}
</div>
</div>
Finally got it sorted with the following change...
foreach($master as $index => $item) {
foreach($item as $key => $value) {
if($key == 'sub_items') {
$sub = json_decode($value);
unset($item['sub_items']);
$item['sub_items'] = $sub;
}
}
if($category == $item['category']) {
array_push($items, $item);
}
}
This returned...
...created_at":"2016-11-01 14:19:07","sub_items":["subOne","subTwo","subThree"...
No longer treated as a string it's easy to loop through with Angular. Thanks!

php remove element from array without add key

I want to remove an element from an array (converted from json), but with unset, and reconvert in json, the array become indexed.
Source array:
{"rows":
[{"c":[{"v":"Date(1409052482000)"},{"v":22},{"v":22},{"v":22},{"v":null}]},
{"c":[{"v":"Date(1409052614000)"},{"v":22},{"v":22},{"v":22},{"v":null}]},
{"c":[{"v":"Date(1409052782000)"},{"v":22},{"v":22},{"v":22},{"v":null}]}
]}
Result:
{"rows":
"2":{"c":[{"v":"Date(1409052614000)"},{"v":22},{"v":22},{"v":22},{"v":null}]},
"3":{"c":[{"v":"Date(1409052782000)"},{"v":22},{"v":22},{"v":22},{"v":null}]}
}}
the problem is the "2" and "3" keys. I don't want this keys, because I use the data for google chart, and is sensible for this index key.
PHP code:
$tempdata = json_decode($jsonTempLog, TRUE);
foreach ($tempdata['rows'] as $key => $row) {
if ( $logtime < $showtime) {
unset($tempdata['rows'][$key]);
}
}
echo json_encode($tempdata);
How can I remove element from array, keep the original json syntax?
Just do this:
$tempdata["rows"] = array_values($tempdata["rows"]);
echo json_encode($tempdata);
Otherwise JSON thinks you're sending an associative array rather a numeric one
this is how i work with :
unset($infos[$i]);
$infos = array_values($infos);
maybe like this:
foreach($tempdata as $row){
$tempdata[$rows['keyfield']] = $row;
}

PHP: String in json parse

I am trying to parse a json. I am running this in a foreach loop and if I do the following it works:
$places = array('restaurant', 'store', 'etc')
foreach ($this->placesCachingTypes as $places) {
$places_location_lat = $json_decoded->json[0]->restaurant[0]->geometry->location->lat;
$places_location_lng = $json_decoded->json[0]->restaurant[0]->geometry->location->lng;
}
However, when I do the following, i.e. I change restaurant to $places (I need to do this since I have an array of different places and I want to parse all of them in a foreach loop) it doesn't work.
foreach ($this->placesCachingTypes as $places) {
$places_location_lat = $json_decoded->json[0]->$places[0]->geometry->location->lat;
$places_location_lng = $json_decoded->json[0]->$places[0]->geometry->location->lng;
}
Solution is changing $places to {$places}[0]
The $places array contains keywords, such as restaurant or store. So the [0] is referring to the first one in the json which is why it's needed.
Why do you have this in the first loop:
json[0]->restaurant[0]
json[0]->$restaurant[0]
But then in the next you have:
json[0]->$places[0]
json[0]->$places[0]
Perhaps you are parsing the JSON incorrectly and it should be:
foreach ($this->placesCachingTypes as $places) {
$places_location_lat = $json_decoded->json[0]->places[0]->geometry->location->lat;
$places_location_lng = $json_decoded->json[0]->places[0]->geometry->location->lng;
}
And then in the first loop, you should do a similar edit to get rid of $restaurant[0]:
foreach ($this->placesCachingTypes as $places) {
$places_location_lat = $json_decoded->json[0]->restaurant[0]->geometry->location->lat;
$places_location_lng = $json_decoded->json[0]->restaurant[0]->geometry->location->lng;
}
Then again, unclear on what value $places has when you loop via foreach ($this->placesCachingTypes as $places) {. It does’t make sense what you would be looping through with the value of $places. And perhaps assigning that $places in the loop object of $json_decoded->json[0]-> is the source of your issues? Need more info from you to confirm this.

PHP JSON encode- Manually assign keys?

I am trying to convert a MySQL query result into JSON within an AJAX request.
My code looks like this at the moment.
$offset = empty($_GET['offset']) ? 0 : $_GET['offset'];
$numimagestodisplay = 3;
$items = array();
$allitems // This is the queryset obtained through a call to a function
foreach ($allitems as $i => &$item)
{
if (($i >= $offset) && (count($items) < $numimagestodisplay))
{
$items[$i] = $item;
}
}
$output = '{"items":'.json_encode($items).'}';
I then want to cycle through the returned results in the javascript calling the above code and need to refer to the array items by their keys (I need to alter some HTML element IDs using these values). However, the JSON is returned in the wrong format.
If I change the line
$items[$i] = $item;
to:
$items[] = $item;
Then I can refer to it by key, however the keys are obviously just 0, 1, 2, whereas I need the key to be the value defined in the loop.
How can I alter the PHP code to return the JSON in the correct format?
Any advice appreciated.
Thanks.
The problem is that arrays in Javascript (and most other languages for that matter) can't have user defined keys. You want your array to be encoded to a JSON object instead of an array (arrays in PHP with user-defined keys are in essence objects). This usually happens automatically, for arrays with non-numeric keys.
In your case, you can use the JSON_FORCE_OBJECT flag:
$output = '{"items":'.json_encode($items,JSON_FORCE_OBJECT).'}';
From the documentation:
Non-associative array output as array: [[1,2,3]]
Non-associative array output as object: {"0":{"0":1,"1":2,"2":3}}

Categories