I have a json string:
$testArray =
{
"Test1": {
"id": "26",
"admin": "Admin TestClient"
},
"Test2": {
"id": "27",
"admin": "Admin TestClient"
},
"Test3": {
"id": "28",
"admin": "Admin TestClient"
}
}
And a variable with id value, say
$idSearch = 28;
Now I need to get its key : "Test3"
I tried :
$NameKey = array_search($idSearch , $testArray->id);
But this gives null
For this, it's better to use a simple loop:
function getById($id) {
foreach ($testArray as $key => $value) {
if ($value['id'] == $id) {
return $key;
}
}
return '';
}
$key = getById(28);
var_dump($key);
array_reduce($testArray, function ($result, $item) use ($idSearch) {
return $result ?: ($item['id'] === $idSearch ? $item : null);
});
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;
}
Hello I've got this really messy JSON that I would like to read data from but I can't think of a way to do it.
It looks like this
https://pastebin.com/55pWWgnK
{
"capacity_test": {
"date": "2017-03-01",
"status": "done",
"PROPERTIES": {
"fail": {
"capacity_test": {
.
.
.
},
"def": [
{
"drop_test": {
"Properties": {
"date": "2017-03-05",
"status": "done"
}
},
"waves_test": {
"date": "2018-03-06",
"status": "done"
}
},
{
"drop_test": {
"Properties": null
},
"waves_test": {
"date": "2018-03-06",
"status": "done"
}
},
{
"drop_test": {
"Properties": null
},
"waves_test": {
"date": "2018-03-06",
"status": "done"
}
}
]
},
"final_test": {
"Properties": null
}
}
}
}
PROPERTIES is not the same as Properties and this json array is recursive, it can have infinite amount of "capacity_test" inside one another.
My issue is that I would like to check if there is a "status" key with no value in there somewhere.
This JSON is quite messy, I tried to come up with a recursive php function such as:
$this->myFunction($json, 'capacity_test');
public function myFunction($json, $step, $status = 0)
{
if ( is_object($json->$step) ) {
if ( isset($json->$step->status) ) {
if ( !empty($json->$step->status) ) {
$status = 1;
}
} else {
foreach ( $json->$step as $item ) {
if ( is_object($item) ) {
$status = $this->myFunction($item, $step, $status);
if ( $status === 0 ) {
exit(0);
}
}
}
}
}
return $status;
}
This doesnt seem to work for me
This piece of code should help you. Implement your own logic, when status is empty.
<?php
$jsonString = '{
"capacity_test": {
"date": "2017-03-01",
"status": "done",
"PROPERTIES": {
"fail": {
"capacity_test": {
"date": "2017-03-02",
"status": "done",
"PROPERTIES": {
"boolean": false
}
},
"def": [
{
"drop_test": {
"Properties": {
"date": "2017-03-05",
"status": "done"
}
},
"waves_test": {
"date": "2018-03-06",
"status": "done"
}
},
{
"drop_test": {
"Properties": null
},
"waves_test": {
"date": "2018-03-06",
"status": "done"
}
},
{
"drop_test": {
"Properties": null
},
"waves_test": {
"date": "2018-03-06",
"status": ""
}
}
]
},
"final_test": {
"Properties": null
}
}
}
}';
$ar = json_decode($jsonString);
function recArr($array) {
foreach ($array as $k => $v) {
if (is_array($v) || is_object($v)) {
recArr($v);
} else {
if ($k == 'status' && $v == '') {
// some empty logic
echo $k;
}
}
}
}
var_dump(recArr($ar));
You can use array_walk_recursive, like so:
$array = json_decode($str, true); // Convert JSON string to array
$hasEmptyStatus = false;
try {
array_walk_recursive($array, function($item, $key) {
if ($key == "status" && $item == "") {
throw new Exception;
}
});
} catch(Exception $e) {
$hasEmptyStatus = true;
}
var_dump($hasEmptyStatus);
This code converts your JSON object into array, then runs recorsively on your array until it finds a key named "status" that it's value is empty, then it throws an exception in order to break the recorsive function since we found it, so no need to keep running on the array.
https://3v4l.org/LTa56
i have the following Array Structure from Facebook Graph API response.
"data": [
{
"actions": [
{
"action_type": "comment",
"value": "2"
},
{
"action_type": "offsite_conversion",
"value": "1606"
}
],
"date_start": "2017-04-03",
"date_stop": "2017-05-02"
},
{
"actions": [
{
"action_type": "post",
"value": "2"
},
{
"action_type": "post_reaction",
"value": "33"
},
{
"action_type": "page_engagement",
"value": "816"
},
{
"action_type": "post_engagement",
"value": "807"
},
{
"action_type": "offsite_conversion",
"value": "1523"
}
],
"date_start": "2017-04-03",
"date_stop": "2017-05-02"
},
]
The Number of values is flexible and i want to get the value from "offsite_conversion". Normally i would do it for example like that:
data['data'][0]['actions']['1']['value']
But in that case this doesn't work because ['1'] is variable.
Use a loop and test the action type.
foreach ($data['data'][0]['actions'] as $action) {
if ($action['action_type'] == 'offsite_conversion') {
$result = $data['value'];
break;
}
}
because "offsite_conversions" is always the last
If $data['data'][0]['actions'][LAST VALUE]['value'] is what you're looking for:
Your idea of counting should work then:
$actions = $data['data'][0]['actions'];
$index = count($actions) - 1;
$value = $actions[$index]['value'];
So not completely clear what are you trying to achieve, but in a simple way you can just iterate over your $data array:
$needed_values = array();
foreach ($data['data'] as $item) {
foreach ($item['actions'] as $action) {
if ($action['action_type'] == 'offsite_conversion') {
$needed_values[] = $action['value'];
}
}
}
Barmar has the best approach if you don't know where it is, but it's much easier if you want the last one:
$result = end($data['data'][0]['actions'])['value'];
Pretend $json holds the data from facebook
<?php
$data = json_decode($json);
$conversions = 0;
foreach ($data as $datum) {
foreach ($datum['actions'] as $action) {
if ($action['action_type'] === 'offsite_convserion') {
$conversions += (int)$action['value'];
break;
}
}
}
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 want to parse an array with PHP's foreach loop to get the object names and values inside the 'ques' array.I want
[
{
"ques": [
{
"name": "comment",
"value": "comment me for the reason",
"sur_id": "1",
"user_id": "admin#gmail.com",
"pagename": "question_response"
},
{
"name": "check-box[]",
"value": "1"
},
{
"name": "radio",
"value": "radio 2"
},
{
"name": "yes",
"value": "no"
}
]
"ques":[
{
"name": "date",
"value": "2015-10-23"
"user_id": "admin1#gmail.com",
},
{
"name": "select-deopdown",
"value": ""
},
{
"name": "true",
"value": "false"
},
{
"name": "number",
"value": "55"
}
]
}
]
I want to separate the name,value and user_id from the 'ques' array:
while ($fetch = mysql_fetch_array($query1)) {
$content = $fetch['CONTENT_VALUES'];
// print_r($content);
$content_value= mb_convert_encoding($content ,"UTF-8");
$datas = json_decode($content, true);
foreach($datas->ques as $values)
{
echo $values->value . "\n";
print_r($values);
}
$test[] = array('ques' => $datas ,'answer'=>$values);
}
If you want to make three different array for each value then create three blank array and then storing corresponding values into them in foreach . Am giving you a common example below
$name = array();
$values= array();
$users = array();
foreach($datas->ques as $values) {
$name[] = $values->name;
$values[] = $values->value;
$users[] = !empty($values->user_id) ? $values->user_id : '';
}
and further you can modify according your need.
Thank you.
This could help
$data = json_decode($json);
$result = [];
foreach($data as $row)
{
foreach($row as $k => $v)
{
$i = 0;
foreach($v as $key => $val)
{
foreach($val as $k1 => $v1)
{
$result[$i][$k1] = $v1;
}
$i++;
}
}
}
echo json_encode($result);
foreach($datas->ques as $values)
{
$name = $values['name'];
$value = $values['value'];
$user_id = $values['user_id'];
}
I solved this by following code.Thanks for 3 of them to guide by giving ideas.
$datas = json_decode($content, true);
foreach($datas as $values)
{
$name = $values['name'];
$value = $values['value'];
$user_id = $values['user_id'];
$test[]= array('user'=>$user,'name'=>$name,'value'=>$value);
}
}