I am wondering how to filter through a result like this properly. What I am doing results in problems. Obviously using a foreach on an array with a single item is not ideal but I don't know exactly how to do it any other way.
// connect with the static file
$json = file_get_contents('resources/assets/datafeeds/brewery_single.json');
$obj = json_decode($json, true);
// create brewery info
foreach($obj['pages'] as $brewery) {
foreach($brewery['results'] as $brewery) {
}
}
I've tried doing something like:
foreach($obj['pages']['results'] as $brewery) {
}
But I get an Undefined index: result errror like this.
Example data with only one result block, my data has multiple:
{
"apiName": "brewery_single",
"apiGuid": "d74e8aa2-4064-44b9-81de-2ceb150882c0",
"generatedAt": 1452761620,
"pages": [
{
"pageUrl": "http://www.brewery-website.com",
"results": [
{
"website": "www.brewery.com/",
"plaats": "Place",
"latlong": [
"53.657856",
"5.032597"
],
"naam": "Brouwerij title",
"provincie": "Noord Brabant",
"afbeelding": "http://www.brewery.com/images/brewery/brewer.jpg",
"actief": "Yes",
"land": "Netherlands",
"adres": "<p><b>Adres:</b><br />Street 40 <br />2388 GP<br /> Province, Netherlands </p>",
"opgericht": "1990"
}
]
},
]
}
Hopefully somebody can help me out so I can properly get my data from an api.
It seems like pages is an array of potentially multiple pages, each of which contains a results array of potentially multiple results. So indeed, two loops are in order:
foreach ($obj['pages'] as $page) {
foreach ($page['results'] as $brewery) {
...
}
}
If you're only ever interested in the first result, you can try to directly access it:
if (isset($obj['pages'][0]['results'][0])) {
echo $obj['pages'][0]['results'][0]['plaats'];
}
But again, the point of this data structure appears to be to account for multiple results, so you may be missing out on some information if you only ever consider the first.
Consult the documentation (which hopefully exists) of that API for exact details on the returned data.
Add an extra check to see if the data that you want is in the array:
if (isset($obj['pages'])) {
foreach($obj['pages'] as $brewery) {
if (isset($brewery['results'])) {
foreach($brewery['results'] as $brewery) {
}
}
}
}
There is syntax error in your code near ['results]
Change from
foreach($obj['pages']['results] as $brewery) {
into
foreach($obj['pages']['results'] as $brewery) {
There is no multiple arrays in results array. So why you need foreach there?
Anyways you can get value of results by providing exact INDEX.
For example: echo $obj['pages']['results]['website'];
Related
i have a pretty weird json here. Im trying to iterate through every subscription object and get some data
Here is the json
{
"result":"success",
"data":{
"subscriptions":[
{
"name":"app_generator",
"expirey":1628188363942,
"hwids":3,
"hwids_used":[
"dc253a62ea65cd92c6cb26f15330cf4a8f9e5c3ecf7caae161a3f97de4c84515",
"efede5757f512f9eae1d600302ca5c4e6a3cadb0658310c91c6da2ada68175f4"
]
},
{
"name":"apple",
"expirey":1625596518277,
"hwids":2,
"hwids_used":[
"dc253a62ea65cd92c6cb26f15330cf4a8f9e5c3ecf7caae161a3f97de4c84515",
"dc253a62ea65cd92c6cb26f15330cf4a8f9e5c3ecf7caae161a3f97de4c84515a"
]
}
]
}
}
The code i tried was:
foreach($json['result']['data']['subscriptions'] as $a)
{
//print_r($a);
$expirey = $a['expirey']
}
Im just getting a lot of errors. Let me know what the correct approach would be. My goal is to mainly get the name & expirey data
I'm sorry if I don't use the correct terminology, I'm still learning. I'm trying to figure out how to search a JSON array that has nested arrays in it for a specific value, and then return an associated value.
My problem is similar to this answered question on StackOverflow (How to search through a JSON Array in PHP), but I want to be able to find an item by id in either people or dog or any other nested array. Essentially I want to convert people below in the foreach to a wildcard.
Here is my JSON data - http://foothillertech.com/student/webdesign/2018/2018benrud2/tinker/dataIntro2/test/data.json
foreach($json->people as $item)
{
if($item->id == "8097")
{
echo $item->content;
}
}
Any help is greatly appreciated.
If id is unique in the data, you can merge the inner arrays and index them by id.
$data = json_decode($json, true);
$merged = array_merge(...array_values($data));
$indexed = array_column($merged, null, 'id');
Then you can look up any of the items by id.
echo $indexed['8097']['content'] ?? 'not found';
This only works if id is unique. If not, indexing by id will result in data loss.
In this case, simply do two loops.
$json = json_decode('{
"people": [
{
"id": "8080",
"content": "foo"
},
{
"id": "8097",
"content": "bar"
}
],
"dogs": [
{
"id": "8081",
"content": "spot"
},
{
"id": "8091",
"content": "max"
}
]
}');
foreach($json as $key=>$value){
//$key = people or dogs
//$value = stdClass()
foreach($value as $item)
{
if($item->id == "8097")
{
echo $item->content;
}
}
}
Output
bar
Sandbox
If we used 8081 instead of 8097 I would expect to get 'spot`. And testing that, I do indeed get that (which is in dogs).
I have a JSON file that, in essence, is structured like this:
[{
"name": "James",
"reviews": [
{
"stars": 5,
"body": "great!"
},
{
"stars": 1,
"body": "bad!"
}
]
},
{
"name": "David",
"reviews": [
{
"stars": 4,
"body": "pretty good!"
},
{
"stars": 2,
"body": "just ok..."
}
]
}]
Now when positing new review data for David to a PHP script, how do I target David's specific "reviews" and append it?
I have already decoded everything correctly and have access to both the decoded file and post information. I just don't know how to target David's specific reviews in the JSON array... Thank you in advance!
UPDATE - Just to be clear, everything is decoded already, the POST data and the JSON file from the server. I just need to know how to target David's reviews specifically and append it.
UPDATE 2 - Everyone, please also understand that this is in the case that the index is not known. Doing [1] would be awesome, but when someone submits, they won't know what index it is. The loop for the rendering is being done in AngularJS btw, so can't assign anything on the PHP side for the front-end.
You will have to make use of a for-loop/foreach to iterate through the array testing where arr['name'] === 'David',
then you can access arr['reviews'].
foreach ($array as $person)
{
if ($person['name'] === 'David')
{
$person['reviews'][] = array("stars"=> 3,"body"=> "pretty cool!");
break;
}
}
Edit:
You could also make a generic function for this
function findElem(arr,field,e)
{
foreach ($arr as $elem)
{
if ($elem[field] === e)
{
return $elem;
}
}
return null;
}
to call:
$elem = findElem(myArray,'name','David');
if ($elem !== null)
$elem[] = array("stars"=> 3,"body"=> "pretty cool!");
Looks like more work, but if you are going to do it repeatedly then this helps.
PHP >= 5.5.0 needed for array_column or see below for an alternate:
$array[array_search('David', array_column($array, 'name'))]['reviews'][] = array(
'stars'=>1,'body'=>'meh'
);
Instead of array_column you can use:
array_map(function($v) { return $v['name']; }, $array);
If you want specifically david's reviews, and only david's reviews... assuming that $array holds the json_decoded array:
$david_reviews = $array[1]["reviews"];
foreach($david_reviews as $review){
//Do code to retrieve indexes of array
$stars = $review["stars"] //5
$body = $review["body"] //Great!
}
If you're looking to grab reviews for each result, then user2225171's answer is what you're looking for.
json_decode($json, true) will return you the simple array of data. Then save what you need and save back with json_encode()
I am requesting my output look like this:
Response
{
error_num: 0
error_details:
[
{
"zipcode": 98119
},
{
"zipcode": 98101
}
]
}
The values are irrelevant for this example.
My code looks like this:
$returndata = array('error_num' => $error_code);
$returndata['error_details'] = $error_msg;
$temp_data = array();
$temp_value = '';
foreach ($zipcodes_array as $value) {
//$temp_data['zipcode'] = $value;
//$temp_value .= json_encode($temp_data);
$temp_value .= '{"zipcode":$value},';
}
//$returndata['test'] = $temp_value;
$returndata['zipcodes'] = $temp_value;
echo json_encode($returndata);
My output varies depending on my different attempts (which you can see with the commented out things) but basically, I don't understand how the 3rd part (the part with the zipcodes) doesn't have a key or a definition before the first open bracket "["
Here is the output for the code above:
{"error_num":0,"error_details":"","zipcodes":"{\"zipcode\":11111},{\"zipcode\":11112},{\"zipcode\":11113},{\"zipcode\":22222},{\"zipcode\":33333},{\"zipcode\":77325},{\"zipcode\":77338},{\"zipcode\":77339},{\"zipcode\":77345},{\"zipcode\":77346},{\"zipcode\":77347},{\"zipcode\":77396},{\"zipcode\":81501},{\"zipcode\":81502},{\"zipcode\":81503},{\"zipcode\":81504},{\"zipcode\":81505},{\"zipcode\":81506},{\"zipcode\":81507},{\"zipcode\":81508},{\"zipcode\":81509},"}
Obviously i did not show the variables being filled/created because its through MySQL. The values are irrelevant. Its the format of the output i'm trying to get down. I don't understand how they have the "zipcode": part in between {} brackets inside another section which appears to be using JSON_ENCODE
It is close but see how it still has the "zipcodes": part in there defining what key those values are on? My question is, is the "response" above being requested by a partner actually in JSON_ENCODE format?? or is it in some custom format which I'll just have to make w/out using any json features of PHP? I can easily write that but based on the way it looks in the example above (the response) I was thinking it was JSON_ENCODE being used.
Also, it keeps putting the \'s in front of the " which isn't right either. I know it's probably doing that because i'm json_encode'ing a string. Hopefully you see what i'm trying to do.
If this is just custom stuff made to resemble JSON, I apologize. I've tried to ask the partner but I guess i'm not asking the right questions (or the right person). They can never seem to give me answers.
EDIT: notice my output also doesn't have any [ or ] in it. but some of my test JSON_ENCODE stuff has had those in it. I'm sure its just me failing here i just cant figure it out.
If you want your output to look like the JSON output at the very top of your question, write the code like this:
$returndata = array('error_num' => $error_code);
$returndata['error_details'] = array();
foreach ($zipcodes_array as $value) {
$returndata['error_details'][] = array('zipcode' => (int)$value);
}
echo 'Response ' . json_encode($returndata);
This will return JSON formatted like you requested above.
Response
{
error_num: 0
error_details:
[
{
"zipcode": 98119
},
{
"zipcode": 98101
}
]
}
Can you just use single ZipCode object as associative array, push all your small ZipCode objects to the ZipCodes array and encode whole data structure. Here is the code example:
$returndata = array(
'error_num' => $error_code,
'error_details' => array()
);
foreach ($zipcodes_array as $value) {
$returndata['error_details'][] = array('zipcode' => $value);
}
echo json_encode($returndata);
I have a php code that reads JSON files. Part of the JSON sample below:
"Main": [{
"count": 7,
"coordinates": [89,77],
"description": "Office",
},{
"count": 8,
"coordinates": [123,111],
"description": "Warehouse",
}]
and I am trying to code PHP to only get the info (count, coordinates, description) of those who's description is included in the criteria like Warehouse. PHP Sample below
$validcriteria = array("Warehouse", "Parking_lot");
How do I do an if-statement to check first if "description" is included in the valid criteria. I tried the code below but it doesn't seem to work right.
$JSONFile = json_decode($uploadedJSONFile, false);
foreach ($JSONFile as $key => $value)
{
if (in_array($key['description'] , $validcriteria))
{
#more codes here
}
}
My code in PHP has been working except when I try to add $key['description'] to try and check the description first if it's valid. My code above is reconstructed to remove sensitive information but I hope you got some idea of what I was trying to do.
When attempting to understand the structure of a parsed JSON string, start with a print_r($JSONFile); to examine its contents. In your case, you will find that there is an outer key 'Main' which holds an array of sub-arrays. You will need to iterate over that outer array.
// Set $assoc to TRUE rather than FALSE
// otherwise, you'll get an object back
$JSONFile = json_decode($uploadedJSONFile, TRUE);
foreach ($JSONFile['Main'] as $value)
{
// The sub-array $value is where to look for the 'description' key
if (in_array($value['description'], $validcriteria))
{
// Do what you need to with it...
}
}
Note: if you prefer to continue setting the $assoc parameter to false in json_decode(), examine the structure to understand how the objects lay out, and use the -> operator instead of array keys.
$JSONFile = json_decode($uploadedJSONFile, FALSE);
foreach ($JSONFile->Main as $value)
{
// The sub-array $value is where to look for the 'description' key
if (in_array($value->description, $validcriteria))
{
// Do what you need to with it...
}
}
You might also consider using array_filter() to do the test:
$included_subarrays = array_filter($JSONFile['Main'], function($a) use ($validcriteria) {
return in_array($a['description'], $validcriteria);
});
// $included_subarrays is now an array of only those from the JSON structure
// which were in $validcriteria
Given your JSON structure, you probably want
foreach($decoded_json['Main'] as $sub_array) {
if (in_array($sub_array['description'], $validation)) {
... it's there ...
}
}
Because you set false to second argument of json_decode function, it's returned as an object,
if you change it to TRUE, the code would work.
http://php.net/manual/en/function.json-decode.php
and you have to change key to value;
foreach ($JSONFile->Main as $key => $value)
{
if (in_array($value->description, $validcriteria))
{
#more codes here
}
}
this code assume your json file has one more depth greater than your example. that's why $JSONFile->Main in the foreach loop.
Try to use that :
if ( array_key_exists('description', $key) )