Accessing nested JSON using PHP - php

I've created the most part and it's working fine. But this is the only JSON that is nested. How do I access it? I've been trying for the longest time, I think I may have a brain freeze because I thought it would be so simple.
Here is the code to GET all reservations from the JSON file:
GET - Gets all Reservation by Status
$app->get('/reservation/:status', function($status) {
$dbHandler = new DatabaseHandler();
$dbHandler->connect();
$reservationArray = $dbHandler->runQueryWithOneParam('SELECT * FROM RestaurantDB.Reservation WHERE STATUS = ?', "s", $status);
$response = array();
$response["error"] = false;
$response["reservations"] = array();
while ($reservation = $reservationArray->fetch_assoc()) {
$tmpReservation = array();
$tmpReservation["ID"] = $reservation["ID"];
$tmpReservation["UserName"] = $reservation["UserName"];
$tmpReservation["NoOfPeople"] = $reservation["NoOfPeople"];
$tmpReservation["DateOfReservation"] = $reservation["DateOfReservation"];
$tmpReservation["TimeOfReservation"] = $reservation["TimeOfReservation"];
$tmpReservation["Status"] = $reservation["Status"];
$tmpReservation["TotalAmount"] = $reservation["TotalAmount"];
$tmpReservation["SpecialRequirement"] = $reservation["SpecialRequirement"];
$tmpReservation["Details"] = array();
$reservationDetailArray = $dbHandler->runQueryWithOneParam('SELECT * FROM RestaurantDB.ReservationDetail WHERE ReservationID = ?', "i", $reservation["ID"]);
while ($reservationDetail = $reservationDetailArray->fetch_assoc()) {
$tmpReservationDetails = array();
$tmpReservationDetails["ItemID"] = $reservationDetail["ItemID"];
$tmpReservationDetails["Quantity"] = $reservationDetail["Quantity"];
$tmpReservationDetails["SubTotal"] = $reservationDetail["SubTotal"];
array_push($tmpReservation["Details"], $tmpReservationDetails);
}
array_push($response["reservations"], $tmpReservation);
}
$dbHandler->disconnect();
echoResponse(200, $response);
});
The JSON is displayed as..
{
"ID": 5,
"UserName": "Coca Cola",
"NoOfPeople": 2,
"DateOfReservation": "1.79",
"TimOfReservation": null,
"Status": null,
"TotalAmount": null,
"SpecialRequirement": 0,
"Details": [
{
"ID": 1,
"ItemID": 3,
"Quantity": 2,
"SubTotal": ""
},
{
"ID": 2,
"ItemID": 4,
"Quantity": 2,
"SubTotal": 1.2
}
]
}
For example I can display the reservation status using the $reservation ["Status"] but I don't seem to know how to get any of the fields from
"Details": [
{
"ID": 1,
"ItemID": 3,
"Quantity": 2,
"SubTotal": ""
},
Here is the PHP code..
<?php
include ('libs\WsURLs.php');
include ('libs\WsConsumer.php');
$wsConsumer = new WsConsumer ();
$_POST = array ();
$result = $wsConsumer->executeGET ( GET_RESERVATION );
$reservations = $result ["reservations"];
// Populating the table
foreach ( $reservations as $reservation) {
echo ('<tr>');
echo ('<td>' . $reservation ["Status"] . '</td>');
echo ('</tr>');
?>

$reservation["Details"] is an array, you access the array elements:
$reservation["Details"][$i]["ItemID"]
is the Item ID of the i'th item in the reservation.

You can loop through the reservation details
foreach($reservation ["Details"] as $key=>value)

See this example you can go through the array and extract the values:
<?php
$json = '{
"ID": 5,
"UserName": "Coca Cola",
"NoOfPeople": 2,
"DateOfReservation": "1.79",
"TimOfReservation": null,
"Status": null,
"TotalAmount": null,
"SpecialRequirement": 0,
"Details": [
{
"ID": 1,
"ItemID": 3,
"Quantity": 2,
"SubTotal": ""
},
{
"ID": 2,
"ItemID": 4,
"Quantity": 2,
"SubTotal": 1.2
}
]
}';
$data = json_decode($json, true);
for($i = 0; $i < count($data['Details']); $i++) {
echo '<p>';
foreach($data['Details'][$i] as $key => $value) {
echo $key . ' -> ' . $value . '<br>';
}
echo '</p>';
}
In your case you can do that:
$id_search = 2;
foreach ( $reservations as $reservation) {
for($i = 0; $i < count($reservation['Details']); $i++) {
if($id_search == $reservation['Details'][$i]['ID']) {
echo '<p>';
foreach($reservation['Details'][$i] as $key => $value) {
echo $key . ' -> ' . $value . '<br>';
}
echo '</p>';
}
}
}

Related

Can I get a specific JSON value by Id?

I would like to have the corresponding date of typeId: 11 output from the following JSON.
The order of the typeId's is always different, so it doesn't always work, for example, to always address the second value.
{
"page": 1,
"totalsCount": 1,
"isLastPage": true,
"lastPageNumber": 1,
"firstOnPage": 1,
"lastOnPage": 1,
"itemsPerPage": 50,
"entries": [
{
"id": 60132,
"statusName": "GIT",
"dates": [
{
"orderId": 60132,
"typeId": 7,
"date": "2021-06-03T00:00:00+02:00"
},
{
"orderId": 60132,
"typeId": 11,
"date": "2021-05-28T00:00:00+02:00"
},
{
"orderId": 60132,
"typeId": 16,
"date": "2021-05-27T20:20:28+02:00"
},
{
"orderId": 60132,
"typeId": 2,
"date": "2021-05-27T20:19:21+02:00"
},
{
"orderId": 60132,
"typeId": 4,
"date": "2021-06-03T15:16:14+02:00"
}
]
}
]
}
With my approach so far, I don't get any result:
$json = file_get_contents($orders);
$arr = json_decode($orders);
foreach($arr->entries as $order => $value) {
echo '<th scope="row">' . $value->dates->[typeId='11'].date . '</th>';
}
Where is my mistake here?
You could use array_map():
<?php
$arr = json_decode($json, true);
$result = array_filter(
array_map(
function ($record) {if($record['typeId'] == 11) return $record['date'];}, $arr['dates']
)
);
use array_filter() to remove empty values from the result-set.
working demo
EDIT
With updated json information, you could use:
$obj = json_decode($json);
foreach($obj->entries[0]->dates as $order => $value) {
if($value->typeId == 11) echo '<th scope="row">' . $value->date . '</th>';
}
working demo
For this kind of situation i usually write a simple function like this:
function getDate(array $dates, $typeId) {
foreach ($dates as $date) {
if ($date['typeId'] === $typeId) {
return $date;
}
}
return null;
}
Because the dates is an array you have to iterate over and filter out the proper elements by typeId.
Something like this:
dates.filter(({typeId}) => typeId === 11).shift().date

create tree view like json from existing combined array

I have one combined array of order and its items combined into one array but i am trying to create json structure like order then its items list like wise.
$combinedarray[]=array('orderid'=>1,'partycode'=>10,"item"=>'abc',"price"=>250);
$combinedarray[]=array('orderid'=>1,'partycode'=>10,"item"=>'xyz',"price"=>250);
$combinedarray[]=array('orderid'=>2,'partycode'=>20,"item"=>'pqr',"price"=>250);
$combinedarray[]=array('orderid'=>2,'partycode'=>20,"item"=>'lmn',"price"=>250);
Output should be like
[
"0":[
{
"OrderNo": "1",
"partycode": "10",
"OrderDetails": [
{
"Item": "abc",
"price": 250
},
{
"Item": "xyz",
"price": 250
}
]
}
],
"1":[
{
"OrderNo": "2",
"partycode": "20",
"OrderDetails": [
{
"Item": "pqr",
"price": 250
},
{
"Item": "lmn",
"price": 250
}
]
}
]
]
This is What i Tried
$mainarray = array();
$orderarray = array();
$orderitemarray = array();
if (count(combinedarray) > 0) {
foreach (combinedarray as $obj) {
$orderarray[] = array("orderid" => $obj->orderid);
$orderitemarray[] = array("Item" => $obj->Item, "price" => $obj->price);
}
}
$mainarray[] = array_unique($orderarray);
$mainarray['OrderDetails'] = $orderitemarray;
echo json_encode($mainarray);
$mainarray = array();
foreach ($combinedarray as $x) {
$id = $x['orderid'];
unset($x['orderid']);
if (! isset($mainarray[$id])) {
$mainarray[$id]['OrderNo'] = $id;
}
$mainarray[$id]["OrderDetails"][] = $x;
}
// Now $mainarray has indexes equal to OrderNo. To count it from zero, use array_values
echo json_encode(array_values($mainarray), JSON_PRETTY_PRINT);
demo
By your given array
$combinedarray[]=array('orderid'=>1,'partycode'=>10,"item"=>'abc',"price"=>250);
$combinedarray[]=array('orderid'=>1,'partycode'=>10,"item"=>'xyz',"price"=>250);
$combinedarray[]=array('orderid'=>2,'partycode'=>20,"item"=>'pqr',"price"=>250);
$combinedarray[]=array('orderid'=>2,'partycode'=>20,"item"=>'lmn',"price"=>250);
Here is my solution for this
$new = array();
foreach($combinedarray as $r){
$new[$r['orderid']]['orderid'] = $r['orderid'];
$new[$r['orderid']]['partycode'] = $r['partycode'];
$new[$r['orderid']][] = array("item"=>$r['item'],"price"=>$r['price']);
}
$json = json_encode($new);
echo '<pre>';print_r($new);
echo $json;

Store object into array and group all array with the same value in PHP

I'm working on array right now and I need to arrange this based on value.
{
"data": {
"id": 2,
"title": "second evaluation form",
"emp_position": "System Architecture",
"rating": 5,
"segments": [
{
"segment_name": "Job Role ",
"question": "How old are you?"
},
{
"segment_name": "360 Segments",
"question": "What is your food?"
},
{
"segment_name": "360 Segments",
"question": "sample question"
},
]
}
}
What I need to do is to store this object into array and group all question based on segment_name like this:
{
"data":[
{
"id": 2,
"title": "second evaluation form",
"emp_position": "System Architecture",
"rating": 5,
"segments": [
{
"segment_name": "Job Role "
"question_collection": [
{
"id": 4,
"question": "How old are you?"
}
]
},
{
"segment_name": "360 Segments",
"question_collection":[
{
"id": 1,
"question": "What is your food?"
},
{
"id": 2,
"question": "sample question"
}
]
},
]
}
]
}
And this is what I've tried to do:
$array_value =[];
foreach ($query AS $key => &$data) {
$array_value['id'] = $data['id'];
$array_value['title'] = $data['title'];
$array_value['emp_position'] = $data['position'];
$array_value['rating'] = $data['rating_count'];
if ( is_array($data) ) {
$array_value['segments'][$key]['segment_name'] = $data['segment'];
$array_value['segments'][$key]['question'] = $data['question'];
}
}
Collection function might help you find your solution.
$json = '{"data":{"id":2,"title":"second evaluation form","emp_position":"System Architecture","rating":5,"segments":[{"segment_name":"Job Role ","question":"How old are you?"},{"segment_name":"360 Segments","question":"What is your food?"},{"segment_name":"360 Segments","question":"sample question"}]}}';
$array = json_decode($json, true);
$coll = collect($array['data']['segments']);
$coll = $coll->groupBy('segment_name');
dump($coll);
Hope this helps you.Let me know if any problem
Do it like below:-
<?php
$json = '{
"data": {
"id": 2,
"title": "second evaluation form",
"emp_position": "System Architecture",
"rating": 5,
"segments": [
{
"segment_name": "Job Role ",
"id": 4,
"question": "How old are you?"
},
{
"segment_name": "360 Segments",
"id": 1,
"question": "What is your food?"
},
{
"segment_name": "360 Segments",
"id": 2,
"question": "sample question"
}
]
}
}
';
$query = json_decode($json,true);
$segment_array = [];
foreach($query['data']['segments'] as $arr){
$segment_array[$arr['segment_name']]['segment_name'] = $arr['segment_name'];
$segment_array[$arr['segment_name']]['question_collection'][] = ['id'=>$arr['id'],'question'=>$arr['question']] ;
}
$query['data']['segments'] = array_values($segment_array);
echo json_encode($query,JSON_PRETTY_PRINT);
OUTPUT:- https://eval.in/902194
Try this solution, You can loop by array and group all keys
$json = '{
"data": {
"id": 2,
"title": "second evaluation form",
"emp_position": "System Architecture",
"rating": 5,
"segments": [
{
"segment_name": "Job Role ",
"question": "How old are you?"
},
{
"segment_name": "360 Segments",
"question": "What is your food?"
},
{
"segment_name": "360 Segments",
"question": "sample question"
}
]
}
}';
$data = json_decode($json,true);
$segments = $data['data']['segments'];
$new_segemnts = array();
foreach($segments as $segemnt)
{
$key = $segemnt['segment_name'];
$new_segemnts[$key]['segment_name']=$segemnt['segment_name'];
$new_segemnts[$key]['question_collection'][]=array("question"=>$segemnt['question']);
}
$data['data']['segments'] = array_values($new_segemnts);
echo json_encode($data,JSON_PRETTY_PRINT);
DEMO
Here try my answer. I've just editted your existing code so you won't confuse that much. Nothing much to explain here. I included some explaination in my comment.
CODE
$array_value =[];
foreach ($query AS $key => &$data) {
$array_value['id'] = $data['id'];
$array_value['title'] = $data['title'];
$array_value['emp_position'] = $data['position'];
$array_value['rating'] = $data['rating_count'];
if ( is_array($data) ) {
// Check if segment is already added
$has_segment = false;
$segment_key = null;
foreach($array_value['segments'] as $key2 => $val){
//If segment is already added get the key
if($val['segment_name'] == $data['segment']){
$segment_key = $key2;
$has_segment = true;
break;
}
}
// if segment does not exists. create a new array for new segment
if(!$has_segment){
$array_value['segments'] = array();
}
// If new segment, get the index
$segment_key = count($array_value['segments']) - 1;
// If new segment, create segment and question collection array
if(!array_key_exists('question_collection', $array_value['segments'][$segment_key])){
$array_value['segments'][$segment_key]['segment_name'] = $data['segment'];
$array_value['segments'][$segment_key]['question_collection'] = array();
}
//Add the id for question collectiona rray
$array_value['segments'][$segment_key]['question_collection'][] = array(
"id" => $data['question_id'],
"question" => $data['question']
);
}
}

Merge results of single JSON output with PHP

I have a JSON array as per below:
{
"aaData": [
{
"Date_time": "23",
"traffic": "22",
"direction": "sent"
},
{
"Date_time": "24",
"traffic": "55",
"direction": "sent"
},
{
"Date_time": "25",
"traffic": "60",
"direction": "sent"
},
{
"Date_time": "26",
"traffic": "43",
"direction": "sent"
},
{
"Date_time": "27",
"traffic": "50",
"direction": "sent"
},
{
"Date_time": "23",
"traffic": "50",
"direction": "received"
},
{
"Date_time": "24",
"traffic": "42",
"direction": "received"
},
{
"Date_time": "25",
"traffic": "52",
"direction": "received"
},
{
"Date_time": "26",
"traffic": "47",
"direction": "received"
},
{
"Date_time": "27",
"traffic": "36",
"direction": "received"
}
]
}
What I'd like to do with it is combine all the results with the same date into a single entry - so for date_time 23 I want it to appear like this
"Date_time": "23",
"traffic-sent": "22",
"traffic-received": "50"
I'd like to do this with PHP if possible? The data is coming from two separate mySQL queries, coming from to different mySQL databases. I've tried combining the output of the query to do what I need (tried Joins and Unions) but can't get past the separation of the results as per my first example.
The part of the SQL query creating the JSON looks like this:
while($row = mysqli_fetch_assoc($result)) {
$model[$i]['Date_time'] = $row['the_day'];
$model[$i]['traffic'] = $row['traffic'];
$model[$i]['direction'] = $row['TABLE_NAME'];
$i++;
}
And the SQL looks like this:
(SELECT
DAY(`Time`) AS the_day,
count(accounts.accName) AS traffic,
"sent" AS TABLE_NAME
FROM
bss.ss_sent LEFT JOIN bss.accounts ON ss_sent.Customer = accounts.accName
WHERE
YEARWEEK(`Time`) = YEARWEEK(CURRENT_DATE)
AND
Customer != " "
AND
accShortName = "QRR"
GROUP BY
the_day)
UNION
(SELECT
DAY(Date_time) AS the_day,
count(AS_Task) AS traffic,
"received" AS TABLE_NAME
FROM
im_stats.as_counter
WHERE
AS_Task = "QRR3 Incoming"
AND
YEARWEEK(Date_time) = YEARWEEK(CURRENT_DATE)
GROUP BY
the_day
Order by the_day)
IF anyone can advise of a way to combine the results I'd very much appreciate it.
UPDATE:
This is how I've entered Populus's code:
$i = 0;
while($row = mysqli_fetch_assoc($result)) {
$model[$i]['Date_time'] = $row['the_day'];
$model[$i]['traffic'] = $row['traffic'];
$model[$i]['direction'] = $row['TABLE_NAME'];
$i++;
}
$combined = array();
foreach ($model as $val) {
$date_time = $val['Date_time'];
if (!isset($combined[$date_time)) {
$combined[$date_time] = array(
'Date_time' => $date_time,
'traffic_sent' => 0,
'traffic_received' => 0,
);
}
if ('received' == $val['direction']) {
$combined[$date_time]['traffic_received'] += $val['traffic'];
} else {
$combined[$date_time]['traffic_sent'] += $val['traffic'];
}
}
header('Content-type: application/json');
print json_encode(array('aaData' => $combined), JSON_PRETTY_PRINT);
This could probably be done using SQL (which you haven't provided), but if you really want PHP:
$combined = array();
foreach ($model as $val) {
$date_time = $val['Date_time'];
if (!isset($combined[$date_time])) {
$combined[$date_time] = array(
'Date_time' => $date_time,
'traffic_sent' => 0,
'traffic_received' => 0,
);
}
if ('received' == $val['direction']) {
$combined[$date_time]['traffic_received'] += $val['traffic'];
} else {
$combined[$date_time]['traffic_sent'] += $val['traffic'];
}
}
Your desired array is now in $combined. If you don't want the keys, you can remove it:
$result = array_values($combined);
Try it this way:
while($row = mysqli_fetch_assoc($result)) {
if ($row['direction'] == 'sent')
$dt[$row['Date_time']]['traffic-sent'] += $row['traffic'];
elseif ($row['direction'] == 'recieved')
$dt[$row['Date_time']]['traffic-recieved'] += $row['traffic'];
}
foreach ($dt as $date) {
echo "Date_time: " . key($date) . ",<br/>" .
"traffic_sent: " . $date['traffic-sent'] . ",<br/>" .
"traffic-recieved: " . $date['traffic-recieved'] . "<br/><br/>";
}

PHP ARRAY and SUB ARRAYS

So i have the following array structure:
{
"_": {
"APP_ID": "server_tracked"
},
"success": true,
"requestTime": "2013-09-14T15:05:28-07:00",
"shard": "North_America:OTg0ZGYzNjA0OGYxNjAyNWUzZjVlNTQwZDk4YTdjNTYzMGE3NTA4Ng",
"player": {
"accountId": xxx,
"summonerId": xx,
"name": "xx",
"icon": xx,
"internalName": "xx",
"level": xx
},
"data": {
"lifetimeStatistics": {
"array": [
{
"count": 1,
"statType": "TOTAL_SESSIONS_PLAYED",
"dataVersion": 0,
"value": 1,
"championId": 111,
"futureData": null
},
{
"count": 0,
"statType": "TOTAL_SESSIONS_LOST",
"dataVersion": 0,
"value": 0,
"championId": 111,
"futureData": null
},
[...]
And i want to search for a "sub array" where the value "championId" = x and statType = y.
I would then have the [x] if that array, and i should then be able to return any value in that array.
here is some of the PHP code i currently have:
$result = json_decode($response -> raw_body);
$array = $result->data->lifetimeStatistics->array;
$search1 = x;
$search2 = y;
$cluster=false;
foreach ($array as $n=>$c) {
if (in_array($search, $c)) {
$cluster=$n; break;
}
}
As additional information then i am using $response = Unirest::get to get the array.
EDIT with full code:
$result = json_decode($response -> raw_body);
$haystack = $result->data->lifetimeStatistics->array;
$searchx = x;
$searchy = y;
$arrayNumber = null;
foreach ($haystack as $n=>$c) {
if ($c->championId === $searchx && $c->statType === $searchy) {
$arrayNumber = $n;
}
}
// We now get the value from that array
$array = $result->data->lifetimeStatistics->array[$arrayNumber]->value;
return $array;
You found the answer, however needs some tweaks.
$result = json_decode($response -> raw_body);
$haystack = $result->data->lifetimeStatistics->array;
$searchx = "x"; // fill as required
$searchy = "y"; // fill as required
$cluster=null;
foreach ($haystack as $n=>$c) {
if ($c["championId"] === $searchx && $c["statType"] === $searchy) {
$cluster=$n; break;
}
}
if (is_null($cluster)) die("Not found?!"); //do whatever you want if not found

Categories