Split Json object into multiple json objects in PHP - php

I'm a newbie to PHP and I want to split a json object that I have stored in a variable into multiple json objects.
My input looks like this :
{
"results":[
{
"id":"001",
"items":{
"item11":"value1",
"item12":"value2",
"item13":"value3"
},
{
"id":"002",
"items":{
"item21":"value1",
"item22":"value2",
"item23":"value3"
},
{
"id":"003",
"items":{
"item31":"value1",
"item32":"value2",
"item33":"value3"
}]
}
I want to first extract each id and store it into a variable and associate to each id the correspondant json that will look like this :
$id1 = "001";
{
"item11":"value1",
"item12":"value2",
"item13":"value3"
}

Try this loop over each record and save it in result.
$json=json_decode($str,true);
array_map(function($value) use (&$results){
$results[$value['id']]=json_encode($value['items']);
return $results;
}
,$json['results']);
print_r($results);
output
Array (
[001] => {"item11":"value1","item12":"value2","item13":"value3"}
[002] => {"item21":"value1","item22":"value2","item23":"value3"}
[003] => {"item31":"value1","item32":"value2","item33":"value3"} )

if you want to display every array item in results, you can use extract($arr['results'])
but if you want to have specific name you should use loops to do it, depend on your pattren

Related

Extract particular array from multidimensional array

I have a JSON array of data that I am trying to extract particular value/keys(?) from, and would like to add them into a new array.
The array looks like this:
{ "total':2000,
"achievements":[
{
"id":6,
"achievement":{},
"criteria":{
"id":2050,
"is_completed":false
},
"completed_timestamp":1224053510000
},
{
"id":8,
"achievement":{},
"criteria":{
"id":1289,
"is_completed":true
},
"completed_timestamp":0000000
}
]
}
I want to search for true in the is_completed, and then add the id from that array into a new array.
Basically, find the id's of all the key/array (sorry unsure of terminology) where is_completed is true.
I've tried something simple like finding trying to find the key of an ID, but struggling to get that to work. And also seen some of the multi-level for loop examples but can't get them to work for my data.
Example:
$key = array_search('1289', array_column($array, 'id'));
As pointed out in the comments, you could combine array_filter (to filter completed events) and array_column (to extract their IDs).
$completedAchievements = array_filter(
$array->achievements,
static function (\stdClass $achievement): bool {
return $achievement->criteria->is_completed === true;
}
);
$completedAchievementsIds = array_column($completedAchievements, 'id');
print_r($completedAchievementsIds); // Array([0] => 8)
Note: the code above supposes your JSON was decoded as an object. If it was decoded as an array, just replace -> syntax with the corresponding array index access.
Demo

Array_map through a array of objects and grab properties

So I have a var_dump($instagram->get_images()); that gives me the following output:
I want to use array_map to map through all the properties and use them inside a foreach loop later on.. but I'm running into some issues:
Here is the attempt that I have:
$mediaUrls = array_map(function($entry) {
return [
'media_url' => $entry['media_url'],
];
}, $instagram->get_images());
I'm getting back the following error:
Could someone assist me on properly array_mapping through the objects and then later be able to use foreach ($MediaUrls as $media) etc...
The error is correct. You're using array map on an object. But the object does have a ->data property that is an array. But the items in the array are objects, so you'll need to refer to their properties rather than using array syntax.
$images = $instagram->get_images();
$mediaUrls = array_map(function($entry) {
return [
'media_url' => $entry->media_url,
];
}, $images->data);
Couple of suggestions. You said, "I want to use array_map to map through all the properties and use them inside a foreach loop later on."
You can reiterate $images->data later on, so I don't really see the value of making another array just for that purpose
foreach ($images->data as $imageData) {
// do something with $imageData->media_url
}
This would be almost exactly the same as iterating the array you're making with array_map.
foreach ($images->data as $imageData) {
// do something with $imageData['media_url']
}
If you want to get an array of just the urls, you can do it more simply with array_column.
$images = $instagram->get_images();
$mediaUrls = array_column($images->data, 'media_url');
(This won't give you the same result. It will be an array of strings rather than an array of arrays.)

Modify JSON Feed With php

I have a JSON Feed which is accessed by an api.
The json feed it returns is as below:
[
{
"isoDate":"2017-09-15T00:00:00.0000000",
"events":[
{
"id":"-7317",
"name":"Exhibition SKMU: The collection 2015-2017",
},
{
"id":"-91417",
"name":"Torget - a multi cultural meeting place in Geilo",
}
]
},
{
"isoDate":"2017-09-16T00:00:00.0000000",
"events":[
{
"id":"-7317",
"name":"Exhibition SKMU: The collection 2015-2017",
},
{
"id":"-91417",
"name":"Torget - a multi cultural meeting place in Geilo",
}
]
}
]
I need the isoDate to be listed with each event instead of individually.
e.g.
[
{
"events":[
{
"isoDate":"2017-09-15T00:00:00.0000000",
"id":"-7317",
"name":"Exhibition SKMU: The collection 2015-2017",
},
{
"isoDate":"2017-09-15T00:00:00.0000000",
"id":"-91417",
"name":"Torget - a multi cultural meeting place in Geilo",
}
]
},
{
"events":[
{
"isoDate":"2017-09-16T00:00:00.0000000",
"id":"-7317",
"name":"Exhibition SKMU: The collection 2015-2017",
},
{
"isoDate":"2017-09-16T00:00:00.0000000",
"id":"-91417",
"name":"Torget - a multi cultural meeting place in Geilo",
}
]
}
]
Can this be achieved with php? Basically fetch that feed from a url and then display it in my preferred format?
So this is what you have to do, to get back your desired format of the json,
$json is your json string:
$eventList = json_decode($json);
foreach($eventList as $eventEntry){
$isoDate = $eventEntry->isoDate;
foreach($eventEntry->events as $subEventEntry){
$subEventEntry->isoDate = $isoDate;
}
//delete the isoDate from outer
unset($eventEntry->isoDate);
}
echo json_encode($eventList);
So basically, you are first decoding your json into php structure, apply your changes and after that, encode it back. Note here, that I have not appened true as second parameter for the $json_decode, but working with the resulting object.
Also: Your json is not standard comform and could result in errors. PHP will properly not decode it, because your object end with a comma. The last element of an object should be without comma. Instead of
{
"id":"-91417",
"name":"Torget - a multi cultural meeting place in Geilo",
}
make it like this:
{
"id":"-91417",
"name":"Torget - a multi cultural meeting place in Geilo"
}
I know, this can be a problem, when you get it from an API, but this is another problem of itself...
EDIT:
To get every "events" into one big array, you have to store them just like your imagination ;) . Think it like this: $subEventEntry holds one "events"-object. Because you are iterating both levels, you see everyone object of them. My suggestion would be to store them in a new array, and recreating the structure around it:
$everything = new stdClass();
$everything->events = array();
and then, in the inner loop:
foreach($eventList as $eventEntry){
$isoDate = $eventEntry->isoDate;
foreach($eventEntry->events as $subEventEntry){
$subEventEntry->isoDate = $isoDate;
$everything->events[] = $subEventEntry; // <-- this has to be added
}
//delete the isoDate from outer
unset($eventEntry->isoDate);
}
When recreating the structure, and you don't need the old structure anymore you could remove the unset.
Just remeber every [ ] pair in the json represents an array, every { } pair an object (stdClass). The name of this object/array is referenced -> by its class property in the superobject.
Yes you can using json_decode() function for example:
$yourjson;/* your json */
$events = json_decode($yourjson, true);
foreach($events as $event){
echo $event["isoDate"];
}
You can use json_decode to decode the json object to php array then modify the array and encode it using json_encode

How to add custom prefix to json output with PHP

I want to add some string before the data derived from mySQL. And output them in JSON. I can fetch out the data from mySQL right for my needs. But I cannot add the prefix string to the right format.
The expected json format
{
"message": "",//i can do this
"value": [//but I can't do this the "value":[
{
"excName": "Mark",
"excSup": "chunyun",
"excId": 20001
}, {
"excName": "orion-01",
"excSup": "orion-01",
"excId": 20000
}
]
}
PHP
while ($rec_qXcur=mysqli_fetch_assoc($sql_qXcur)){
$data[] = array(
"excId"=>$rec_qXcur['exc_id'],
"excTitle"=>$rec_qXcur['exc_name'],
"excSup"=>$rec_qXcur['exc_sup']
);
}
//return json data
echo json_encode($data);
From PHP I got this :
{
"message":"",
//"value":[//this is missing
"0":{//not need
"excId":"234",
"excTitle":"Simon Cabaret - Regular Seat ",
"excSup":"simon"
},
"1":{//not need
"excId":"245",
"excTitle":"Simon Cabaret - VIP Seat (01Nov15 - 30Apr16)",
"excSup":"simon"
}
According to the expected json format. I missed "value":[. I tried adding it to the $data but it's not working.
You are just adding them to data. You need to add them to the value array.
So json_encode() is probably creating an object literal {} because your array has both named elements and sequential elements. Once it only contains sequential elements, json_encode() should (I believe) return an array literal [];
$data = array(
'message' => 'Your message here',
'value' => array()
);
while ($rec_qXcur=mysqli_fetch_assoc($sql_qXcur)){
$data['value'][] = array(
"excId"=>$rec_qXcur['exc_id'],
"excTitle"=>$rec_qXcur['exc_name'],
"excSup"=>$rec_qXcur['exc_sup']
);
}
echo json_encode($data);

Navigating a returned object

In PHP I have a multidimensional object created from looping through a list of ids
$summary = array();
foreach ( $request->id as $id ) {
...
$summary[] = $summary_data;
}
it's then passed to my javascript.
return json_encode(array('summary' => $summary));
Not sure how to navigate the returned object correctly. Do I have to use the original list of id's, and use that as an index against this object? Or is there a better way to keep track of this?
End result, I want a select box such that when a new item is selected, its data is displayed.
A general JSON object would look like this (trying to put all possible cases):
{
"key1":"value1",
"subObject":{
"subKey1":"subValue1",
"subKey2":"subValue2"
},
"arrayOfSubObjects":[
{"subKey3":"subValue3"},
{"subKey4":"subValue4"}
]
}
You can reference any element of a JSON object with jsonObject.key, but remember those part between [] are arrays so you'll need to index them as if they were in an array so:
// to point subKey1:
jsonObject.subObject.subKey1;
// to point subKey3
jsonObject.arrayOfSubObjects[0].subKey3;
OR
// to point subKey1:
jsonObject["subObject"]["subKey1"];
// to point subKey3
jsonObject["arrayOfSubObjects"][0]["subKey3"];
note the 0 has no quotes because it's an index.

Categories