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
Related
I am calling the Shopify admin api.
When I use the REST API, I get beautiful JSON objects in my responses.
[{
{
"id": 7036594978985,
"title": "7 Shakra Bracelet",
"body_html": "<p>7 chakra bracelet, in blue or black.</p>",
"vendor": "Company 123",
"product_type": "Bracelet",
"created_at": "2021-06-17T17:45:05-04:00",
"handle": "chain-bracelet",
"updated_at": "2021-06-23T20:08:21-04:00",
"published_at": "2021-06-17T17:45:04-04:00",
"template_suffix": null,
"published_scope": "web",
"tags": "Beads, Bracelet",
"admin_graphql_api_id": "gid://shopify/Product/7036594978985",
"variants": [
{
"id": 40671266963625,
"product_id": 7036594978985,
"title": "Blue",
"price": "42.99",
"sku": null,
"position": 1,
"inventory_policy": "deny",
"compare_at_price": "44.99",
"fulfillment_service": "manual",
"inventory_management": null,
"option1": "Blue",
}
},
{
id: 7036594978986
...
]
However, if I use GraphQL I end up with a bunch of edges and nodes that don't play well with my front end JS.
{
"products": {
"edges": [
{
"node": {
"description": "Sleek and black",
"featuredImage": {
"id": "gid://shopify/ProductImage/15464783282345",
"originalSrc": "https://cdn.shopify.com/s/files/1/0268/1005/6873/products/bb20.jpg?v=1602116082"
},
"handle": "skirt",
"id": "gid://shopify/Product/4773734482089",
"images": {
"edges": [
{
"node": {
"id": "gid://shopify/ProductImage/15464783282345",
"originalSrc": "https://cdn.shopify.com/s/files/1/0268/1005/6873/products/bb20.jpg?v=1602116082"
}
},
{
"node": {
"id": "gid://shopify/ProductImage/26072838406313",
"originalSrc": "https://cdn.shopify.com/s/files/1/0268/1005/6873/products/bb7.jpg?v=1612636091"
}
},
{
"node": {
"id": "gid://shopify/ProductImage/26072838373545",
"originalSrc": "https://cdn.shopify.com/s/files/1/0268/1005/6873/products/bb6.jpg?v=1612636091"
}
}
]
},
I'd like to flatten the array a little bit by replacing all edges and nodes with the friendly minimal JSON structure.
From this:
{
"products": {
"edges": [
{
"node": {
"description": "Sleek and black",
"featuredImage": {
"id": "gid://shopify/ProductImage/15464783282345",
"originalSrc": "https://cdn.shopify.com/s/files/1/0268/1005/6873/products/bb20.jpg?v=1602116082"
},
To this:
{
"products": [
{
"description": "Sleek and black",
"featuredImage": {
"id": "gid://shopify/ProductImage/15464783282345",
"originalSrc": "https://cdn.shopify.com/s/files/1/0268/1005/6873/products/bb20.jpg?v=1602116082"
},
I'd like to be able to call a recursive PHP function to replace all nodes and edges nested in the array.
I tried this, but I think it causes iteration issues.
public function parse_and_remove (&$arr) {
foreach ($arr as $key => $val) {
if (($key == 'edges' || $key == 'node') && (is_array($val) || is_object($val))) {
$arr = $val;
$val = $this->parse_and_remove($val);
} else if (is_array($val) || is_object($val)) {
$val = $this->parse_and_remove($val);
} else {
}
}
return $arr;
}
PART II
How is everyone okay with this kind of response in GraphQL? It's a pain to work with on the front end where API responses are often consumed. Don't give me the array of edges and the node then finally the object. I just want that array of objects :)
I finally created a function that did it. It is terribly inefficient because every time I move a node up to replace the parent, I break and restart the entire loop in order to be able to parse the parent again.
$nice_data = $this->move_value_at_node_to_parent($response['body']['data'], 'node');
$nice_data2 = $this->move_value_at_node_to_parent($nice_data, 'edges');
the function: (no indentation because I like prefer the ease of repetition with code alignment - * the foreach loops are nested)
public function move_value_at_node_to_parent($obj, $key_name) {
// make array
$obj_string = json_encode($obj);
$arr = json_decode($obj_string, true);
// do this a bunch to avoid index problems
for ($i=0; $i < 1000; $i++) {
if(!is_array($arr)) continue;
foreach ($arr as $key => $val) {
if($key == $key_name) {
$arr = $val;
break;
}
$arr2 = $arr[$key];
if(!is_array($arr2)) continue;
foreach ($arr2 as $key2 => $val2) {
if($key2 == $key_name) {
$arr[$key] = $val2;
break;
}
$arr3 = $arr[$key][$key2];
if(!is_array($arr3)) continue;
foreach ($arr3 as $key3 => $val3) {
if($key3 == $key_name) {
$arr[$key][$key2] = $val3;
break;
}
$arr4 = $arr[$key][$key2][$key3];
if(!is_array($arr4)) continue;
foreach ($arr4 as $key4 => $val4) {
if($key4 == $key_name) {
$arr[$key][$key2][$key3] = $val4;
break;
}
$arr5 = $arr[$key][$key2][$key3][$key4];
if(!is_array($arr5)) continue;
foreach ($arr5 as $key5 => $val5) {
if($key5 == $key_name) {
$arr[$key][$key2][$key3][$key4] = $val5;
break;
}
$arr6 = $arr[$key][$key2][$key3][$key4][$key5];
if(!is_array($arr6)) continue;
foreach ($arr6 as $key6 => $val6) {
if($key6 == $key_name) {
$arr[$key][$key2][$key3][$key4][$key5] = $val6;
break;
}
$arr7 = $arr[$key][$key2][$key3][$key4][$key5][$key6];
if(!is_array($arr7)) continue;
foreach ($arr7 as $key7 => $val7) {
if($key7 == $key_name) {
$arr[$key][$key2][$key3][$key4][$key5][$key6] = $val7;
break;
}
}
}
}
}
}
}
}
}
return $arr;
}
i have json file like below:
{
"data": [
{
"id": 8921,
"weather": null,
"status": "TT",
}, {"id": 8922,
"weather": null,
"status": "TF",
},
{
"id": 8923,
"weather": null,
"status": "NT",
}, {"id": 8922,
"weather": null,
"status": "HT",
}
]
}
i read this and show in table
but i want filter that with status and get just status have TF and size depend on.
old code without check status:
$jsonResult = file_get_contents('1.json');
$content_json = json_decode($jsonResult);
$size=sizeof($content_json->data);
the new code (did'nt work true):
$jsonResult = $jsonResult = file_get_contents('1.json');
$content_json = json_decode($jsonResult);
$content_json = array_filter($content_json['data'], function ($data) {
return $data['status'] != 'HT' or $data['status'] != 'NT';
});
You should iterate over the data array to check the status:
$jsonResult = file_get_contents('1.json');
$content_json = json_decode($jsonResult, true);
$data = $content_json['data'];
$filteredData = [];
foreach($data as $entry){
if($entry['status'] == "TF")
$filteredData[] = $entry;
}
$size = sizeof($filteredData);
Also, your JSON file has a syntax error, remove the commas after the status properties like so:
{
"data": [
{
"id": 8921,
"weather": null,
"status": "TT"
}, {"id": 8922,
"weather": null,
"status": "TF"
}
]
}
Using arrays as opposed to objects (pass true as the second parameter to json_decode()), you can use array_filter() to remove any elements your not interested in...
$content_json = json_decode($jsonResult,true);
$content_json = array_filter($content_json['data'], function ($data) {
return $data['status'] == 'TF';
});
echo count($content_json);
Update:
Your code should be...
$content_json = json_decode($jsonResult, true);
$content_json = array_filter($content_json['data'], function ($data) {
return $data['status'] != 'HT' and $data['status'] != 'NT';
});
Note the ,true on the json_decode() and the condition should be and not or.
I need to give output with 'floorno' and 'units' as key.But after performing array_splice operation 'floorno' and 'units' key are replaced by integer values.
How to replace integer-valued key with text floorno and unit.
Below is my code
$floor = "Ground";
$query = "SELECT id,property_no,status FROM property_details WHERE wing ='$A' AND floor ='$floor'";
$execute = $db->query($query);
$ground = $execute->fetchAll(PDO::FETCH_ASSOC);
$block_A = array("floorno"=>$floor,"units"=>$ground);
$floor = "First";
$query = "SELECT id,property_no,status FROM property_details WHERE wing ='$A' AND floor ='$floor'";
$execute = $db->query($query);
$ground = $execute->fetchAll(PDO::FETCH_ASSOC);
$first = array("floorno"=>$floor,"units"=>$ground);
array_splice($block_A,2,0,$first);
Below is my array o/p:
{
"0": "Second",
"1": [
{
"id": "396",
"property_no": "SSC.A.02.01",
"status": "0"
},
{
"id": "397",
"property_no": "SSC.A.02.02",
"status": "0"
}
],
"2": "First",
"3": [
{
"id": "388",
"property_no": "SSC.A.01.01",
"status": "0"
},
{
"id": "389",
"property_no": "SSC.A.01.02",
"status": "0"
}
],
"floorno": "Ground",
"units": [
{
"id": "379",
"property_no": "SSC.A.00.01",
"status": "0"
},
{
"id": "381",
"property_no": "SSC.A.00.02",
"status": "0"
}
]
}
Helper function for splice with assoc
function array_splice_assoc(&$input, $offset, $length, $replacement)
{
$replacement = (array)$replacement;
$key_indices = array_flip(array_keys($input));
if (isset($input[$offset]) && is_string($offset)) {
$offset = $key_indices[$offset];
}
if (isset($input[$length]) && is_string($length)) {
$length = $key_indices[$length] - $offset;
}
$input = array_slice($input, 0, $offset, TRUE)
+ $replacement
+ array_slice($input, $offset + $length, NULL, TRUE);
}
I have an array which has a key with multiple content. I want to get that array which includes the key that I search .
$arr = json_decode('{"people":[
{
"id": "8080",
"content": "foo",
"member": [123, 456],
"interval": 7
},
{
"id": "8097",
"content": "bar",
"member": [1234, 4567],
"interval": 7
}
]}', true);
$results = array_filter($arr['people'], function($people) {
return $people['id'] == 8080;
});
echo json_encode($results);
This will return:
{"id":"8080","content":"foo","member":[123,456],"interval":7}
I want that:
$results = array_filter($arr['people'], function($people) {
return $people['member'] == 123;
});
And this does not work.
Have somebody an idea?
As #JonStirling said in comment. Use in_array() function.
$arr = json_decode('{"people":[
{
"id": "8080",
"content": "foo",
"member": [123, 456],
"interval": 7
},
{
"id": "8097",
"content": "bar",
"member": [1234, 4567],
"interval": 7
}
]}', true);
$searchId = 123;
$results = array_filter($arr['people'], function($people) use ($searchId) {
return in_array($searchId, $people['member']);
});
echo json_encode($results);
Result:
[{"id":"8080","content":"foo","member":[123,456],"interval":7}]
See if this helps:
$arr = json_decode('{"people":[
{
"id": "8080",
"content": "foo",
"member": [123, 456],
"interval": 7
},
{
"id": "8097",
"content": "bar",
"member": [1234, 4567],
"interval": 7
}
]}', true);
$results = array_filter($arr['people'], function($people) {
for($i=0; $i<count($people['member']); $i++){
return $people['member'][$i] == 123;
}
});
echo json_encode($results);
The out come will be:
[{"id":"8080","content":"foo","member":[123,456],"interval":7}]
If you want to do it withouth 'array_filter' you can try this:
function search($arr, $id, $arrayValue)
{
$people = null;
foreach ($arr['people'] as $a)
{
if ($a['id'] == $id)
{
$people = $a;
}
}
$arrayWeAreLookingFor = null;
foreach ($people as $property => $value)
{
if (is_array($value))
{
foreach ($value as $v)
{
if ($v == $arrayValue)
{
$arrayWeAreLookingFor = $people[$property];
}
}
}
}
return $arrayWeAreLookingFor;
}
var_dump(search($arr, 8080, 123));
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>';
}
}
}