Using php foreach to get a second JSON Nested Array - php

I have a nested array from a json API that usually have zero, one, or two arrays.
I can get it so if the array is empty to display "N/A", and to display only the first ([0]) instance of the array.
However displaying the second array is tripping me up. I know I need to use the foreach to iterate through the PosTags (see below) array, so to extract each Tag value in the body of the foreach loop. However, I can't figure HOW to do this correctly.
My JSON:
[
{
"SectionDetails": [
{
"Description": "Course Description",
"Departments": "Department",
"Credits": "3.00",
"Meetings": [
{
"DOW": "Th",
"Dates": "08-31-2017 to 12-08-2017",
"Times": "03:00 PM - 05:30 PM",
}
],
"PosTags": [
{
"Tag": "HART-ANC"
},
{
"Tag": "ARCH-ARCH"
}
]
}
]
}
]
Current PHP:
$postag = "N/A";
if (isset($sectiondetails->{'PosTags'}))
{
if(!empty($sectiondetails->{'PosTags'})) {
$postag=$sectiondetails->{'PosTags'}[0]->{'Tag'};
}
}
Running a foreach loop like the following displays "Object of class stdClass could not be converted to string" on the line where echo tag is:
if (isset($sectiondetails->{'PosTags'})) {
if(!empty($sectiondetails->{'PosTags'})) {
$postag=$sectiondetails->{'PosTags'};
foreach ($postag as $tag) {
echo $tag;
}
}
}
Ideally I'd like HART-ANC, ARCH-ARCH to be displayed. Thoughts?

Related

Remove the item from array based on child value on object

I've got the following data structure:
Array -> Object -> Array -> Object -> Object
[
{
"id":6834,
"contract_id":13,
"schedule_column_values":[
{
"id":34001,
"field_value":{
"id":324241,
"value":10,
"field":{
"id":1,
"signature":"ios"
}
}
},
{
"id":34001,
"field_value":{
"id":324241,
"value":10,
"field":{
"id":1,
"signature":"android"
}
}
}
]
}
]
What I'm trying to achieve is that if a field has the signature of "android", remove its grandparent object from schedule_column_values. Basically, if a signature is "android", the final data would look like this:
[
{
"id": 6834,
"contract_id": 13,
"schedule_column_values": [
{
"id": 34001,
"field_value": {
"id": 324241,
"value": 10,
"field": {
"id": 1,
"signature": "ios"
}
}
}
]
}
]
This is just an example but the structure is always the same and we always know what signature we're looking for. It could be anything other than android but we know the string we're looking for.
I've tried a nested foreach loop and tried unset but it doesn't seem to work. The other way is I've set a NULL to object value of schedule_column_values when the signature of field is matched, but I cannot have NULL in the object.
What would be a good way to filter out this structure?
This is a perfect use case for array_filter:
$filtered_array = [];
foreach($array as $grandparent){
$filtered_schedules = array_filter(
$grandparent->schedule_column_values,
function($item){
return $item->field_value->field->signature !== 'android';
}
);
$altered_grandparent = clone $grandparent;
$altered_grandparent->schedule_column_values = $filtered_schedules;
$filtered_array[] = $altered_grandparent;
}

Elasticsearch array format for multiple must terms

I'm working on elasticsearch (2.3) and am trying to create a search query. For elasticsearch I need JSON, but I start with a simple php array and encode it to JSON afterwards.
I have a problem with creating the right array format.
This is a small part of the code I'm using:
$params['body']['query']['filtered']['filter']['bool']['must']["term"]['pprCategories']= "category1";
$params['body']['query']['filtered']['filter']['bool']['must_not']['exists']['field'] = "field1";
With an if statement I add a new line:
$params['body']['query']['filtered']['filter']['bool']['must']['term']['country_name']= "country1";
So the total code is:
$params['body']['query']['filtered']['filter']['bool']['must']["term"]['pprCategories']= "category1";
$params['body']['query']['filtered']['filter']['bool']['must_not']['exists']['field'] = "field1";
$params['body']['query']['filtered']['filter']['bool']['must']['term']['country_name']= "country1";
#output
echo "<pre>";
print_r(json_encode($params, JSON_PRETTY_PRINT));
echo "</pre>";
The is the actual result I get from the query I built:
{
"body": {
"query": {
"filtered": {
"filter": {
"bool": {
"must": {
"term": {
"pprCategories": "category1",
"country_name": "country1"
}
},
"must_not": {
"exists": {
"field": "field1"
}
}
}
}
}
}
}
}
However, the desired result would be as follows, i.e. with two elements in the bool/must array:
{
"body": {
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"pprCategories": "category1"
}
},
{
"term": {
"country_name": "country1"
}
}
],
"must_not": {
"exists": {
"field": "field1"
}
}
}
}
}
}
}
}
As you can see the bool/must array contains two conditions instead of just one: pprCategories and country_name are two different 'must' conditions.
Thanks for helping me out!
If you want to add several conditions, you need to understand that bool/must should be an array. You can make your code work like this:
// first create the bool/must array with a single term condition
$params['body']['query']['filtered']['filter']['bool']['must'] = [
[
'term' => [
'pprCategories' => "category1";
]
]
];
// add the must_not condition
$params['body']['query']['filtered']['filter']['bool']['must_not']['exists']['field'] = "field1";
// test your condition
if (...) {
// now add a second constraint to the bool/must array
$params['body']['query']['filtered']['filter']['bool']['must'][] = [
'term' => [
'country_name' => "country1"
]
];
}
I think you should be going this way before taking it to json.
$params['body']['query']['filtered']['filter']['bool']['must'][0]["term"]['pprCategories']= "category1";
$params['body']['query']['filtered']['filter']['bool']['must'][1]["term"]['country_name']= "country1";
$params['body']['query']['filtered']['filter']['bool']['must'][2]["term"]['population_name']= "population1";
$params['body']['query']['filtered']['filter']['bool']['must'][3]["term"]['kilometers_amount']= "55145";

Loop json object as array in PHP

How can i loop the response to get all ids and names?
If the response like this:
{
"Data": [
{
"Id": "4321",
"Name": "Dog"
},
{
"Id": "749869",
"Name": "Cat"
}
]
}
I can get all the ids and names using this code:
foreach (json_decode($response->content)->Data as $resp) {
echo $resp->Id;
echo $resp->Name;
}
But, if the response like this:
{
"Data": {
"dog": {
"Id": "4321",
"Name": "Dog"
},
"cat": {
"Id": "749869",
"Name": "Cat"
}
}
}
How can i get all the ids and names without knowing the amount of the array? Thank you.
You can get PHP to read everything into an (associative where applicable) array.
foreach (json_decode($response->content, true)["Data"] as $resp) { //2nd parameter is to decode as array
echo $resp["Id"];
echo $resp["Name"];
}
Example run: https://eval.in/954621
Alternatively you can do the lazy thing and just cast:
foreach ((array)json_decode($response->content)->Data as $resp) {
echo $resp->Id;
echo $resp->Name;
}
Well if you want to extract all ids into one array (I assume you mean all into one array), to use in a database query as an example. I would recommend you doing like this.
$ids = array_values(array_map(function($animal){
return intval($animal['Id']);
}, json_decode($response->content, true)['Data']));
var_dump($ids);
you do the same ! foreach loop would work on both.
the json response supposed to have the same format every time, unless you have a really weird API.
<?php
$response = json_decode($json);
foreach($response as $animal => $data)
{
echo $animal;
echo $data->id;
echo $data->name;
}

How to get json format for monogo db object [duplicate]

I am using PHP to connect with MongoDB. My code is as follows.
// connect
$m = new MongoClient($con_string); // connect to a remote host at a given port
$db = $m->main;
$customers = $db->customer->find();
i want to return $customers collection as json document to my HTML. How can i do this?
You can do this two ways:
echo json_encode(iterator_to_array($customers));
or you can manually scroll through it:
foreach($customers as $k => $row){
echo json_encode($row);
}
Each of MongoDBs objects should have their __toString() methods correctly implemented to bring back the representation of the value.
This also will work. And you can customize your json as well.
$arr = array();
foreach($customers as $c)
{
$temp = array("name" => $c["name"], "phone" => $c["phone"],
"address" => $c["address"]);
array_push($arr, $temp);
}
echo json_encode($arr);
Other answers work, but it is good to know that the generated JSON will have the following form (in this example I use an hypothetical "name" field for your customers):
{
"5587d2c3cd8348455b26feab": {
"_id": {
"$id": "5587d2c3cd8348455b26feab"
},
"name": "Robert"
},
"5587d2c3cd8348455b26feac": {
"_id": {
"$id": "5587d2c3cd8348455b26feac"
},
"name": "John"
}
}
So in case you don't want the Object _id to be the key of each of your result objects you can add a false parameter to iterator_to_array.
Your code would be:
echo json_encode(iterator_to_array($customers, false), true);
This creates the same result as
$result = Array();
foreach ($customers as $entry) {
array_push($result, $entry);
}
echo json_encode($result, true);
which is an array of JSON objects
[
{
"_id": {
"$id": "5587d2c3cd8348455b26feab"
},
"name": "Robert"
},
{
"_id": {
"$id": "5587d2c3cd8348455b26feac"
},
"name": "John"
}
]

returning index from JSON returned array

Hi guys I was wonder how you can return the index based on ID with the following.
$friends = '{
"data": [
{
"name": "Paul",
"id": "12000"
},
{
"name": "Bonnie",
"id": "120310"
},
{
"name": "Melissa",
"id": "120944"
},
{
"name": "Simon",
"id": "125930"
},
{
"name": "Anthony",
"id": "120605"
},
{
"name": "David",
"id": "120733"
}
]
}';
$obj = json_decode($friends);
for example, I want to get print the name based on ID. I've had a go at using array_search but it didn't like the structure of the array. I will be using it inside a sql loop and passing the ID from the query to return the name string from the array.
print $obj->{'data'}[0]->{'name'};
//where 0 is returned index based on a defined ID.
thanks a lot
The json_decode makes your variables into objects. To do a search, you could use:
// The extra true at the end makes it decode to associative arrays
$json = json_decode($friends, true);
findByName($json, 1234);
function findNameById($obj, $id) {
foreach($obj as $o) {
if($o['id'] == $id) return $o['name'];
}
return false;
}
You will need PHP 5.3 in order to utilize the following closure and enhanced ternary operator (prints name if record is found; otherwise, prints 'No record found.'):
$findById = function($id) use ($friends) {
foreach (json_decode($friends)->data as $friend) {
if ($friend->id === $id) return $friend->name;
}
return;
};
echo $findById('125930') ?: 'No record found.';
Nice thing about this is that you can pass this callable around and it will remember the scope it was defined with. This means that you can pass any ID but the $friends array will always be available to the closure.

Categories