Consolidate JSON array in PHP from MySQL Query Results - php

The existing code looks like this:
function getList(){
$sql = 'SELECT DISTINCT `person`.`person_name` as name, `skill`.`skill_name` as
skill,`skill_linker`.`skill_score`;
$result = $GLOBALS['conn']->query($sql);
if ($result->num_rows > 0) {
$emptyArray = array();
while($row = $result->fetch_assoc()) {
$emptyArray[] = $row;
}
echo json_encode($emptyArray);
}
}
JSON Output from above function:
[{
"name":"Bob Sun",
"skill":"Dancing",
"skill_score":"3"
},
{
"name":"Bob Sun",
"skill":"Surfing",
"skill_score":"2"
},
{
"name":"Bob Sun",
"skill":"Swimming",
"skill_score":"5"
},
{
"name":"Joe Steel",
"skill":"Eating",
"skill_score":"2"
},
{
"name":"Joe Steel",
"skill":"Cooking",
"skill_score":"3"
}]
Instead, I would like the JSON output to look something like this:
[
{
"name": "Bob Sun",
"skills" : [
"Dancing": 3,
"Surfing": 2,
"Swimming": 5
]
},
{
"name": "Joe Steel",
"skills" : [
"Eating": 2,
"Cooking": 3
]
}
]
Can this be done? How can I have it display skills:skill_score for each person if the data coming from the SQL result set is separate? How can I change the code to restructure the JSON data to have semi-categories?

Just transform the array in your while cycle.
while($row = $result->fetch_assoc()) {
$emptyArray[$row['name']]['name'] = $row['name'];
$emptyArray[$row['name']]['skills'][$row['skill']] = $row['skill_score'];
}
Welcome to StackOverflow.

insted of applying json_encode on the final array ,
apply it on row
concatinate all rows
inset final concatinated string into array
this may solve the issue

Related

Group PHP array values based on 2 sub-values

I have called a JSON array from an API and used json_decode to assign them to a PHP variable.
The array looks like this:
[
{
"id": "1",
"abbr": "XXX",
"title": "YYY",
"visible_from_lat": "85",
"visible_to_lat": "-75",
},
{
"id": "2",
"abbr": "AAA",
"title": "BBB",
"visible_from_lat": "85",
"visible_to_lat": "-75",
}
]
The array has approx 50 items in total, all of which have a visible_from_lat and a visible_to_lat. What I need to do is group each items like so:
visible_from_lat > 0 then assign to variable1
visible_from_lat < 0 then assign to variable2
Any idea's how I do this?
Here there is a basic solution, assuming that in data.json file there are your json data:
<?php
$array = json_decode(file_get_contents("data.json"));
$resulSetPositive = [];
$resulSetNegative = [];
foreach ($array as $obj) {
if(isset($obj->visible_from_lat)) {
if($obj->visible_from_lat > 0) {
$resulSetPositive[] = $obj; // add obj to positive result set
}
else if($obj->visible_from_lat < 0) {
$resulSetNegative[] = $obj; // add obj to negative result set
}
}
}
file_put_contents("negative.json", json_encode($resulSetNegative, JSON_PRETTY_PRINT));
file_put_contents("positive.json", json_encode($resulSetPositive, JSON_PRETTY_PRINT));

Group SQL data by JSON arrays

I am working on a page for teachers that shows results of students' performance on a test.
To display a graph I want to use Highcharts JavaScript library.
So far I have a PHP script using PDO to create JSON data that later can be fed to Highcharts from a different page.
My problem:
How do I group all data from the same student in an array? See the last example for what I wish to achieve. Also: I wish to enclose all data in an overarching JSON array.
I want this:
[{
"student": "Andreas",
"level" : [4, 3]
}, {
"student": "Eivind",
"level" : [4, 5]
}, {
"student": "Ole",
"level" : [4, 3]
}]
This is what my PHP looks like:
<?php
require("config.inc.php");
$school = $_GET["school"];
$class = $_GET["class"];
//initial query
$query = 'SELECT student, taskid, level FROM task
WHERE school=' . '"' . $school . '"' . ' AND class=' . '"' . $class . '" ORDER BY student';
//execute query
try {
$stmt = $db->prepare($query);
$result = $stmt->execute();
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Database Error!";
die(json_encode($response));
}
// Finally, we can retrieve all of the found rows into an array using fetchAll
$rows = $stmt->fetchAll();
if ($rows) {
$response["posts"] = array();
foreach ($rows as $row) {
$post = array();
$post["student"] = $row["student"];
$post["level"] = $row["level"];
//update our repsonse JSON data
array_push($response["posts"], $post);
}
// echoing JSON response
echo json_encode($response, JSON_NUMERIC_CHECK);
} else {
$response["success"] = 0;
$response["message"] = "No Post Available!";
die(json_encode($response));
}
?>
This is what I get from the PHP:
{
"posts": [
{
"student": "Andreas",
"level": 4
},
{
"student": "Andreas",
"level": 3
},
{
"student": "Eivind",
"level": 4
},
{
"student": "Eivind",
"level": 5
},
{
"student": "Ole",
"level": 4
},
{
"student": "Ole",
"level": 3
}
]
}
var data=[
{ "category" : "Search Engines", "hits" : 5, "bytes" : 50189 },
{ "category" : "Content Server", "hits" : 1, "bytes" : 17308 },
{ "category" : "Content Server", "hits" : 1, "bytes" : 47412 },
{ "category" : "Search Engines", "hits" : 1, "bytes" : 7601 },
{ "category" : "Business", "hits" : 1, "bytes" : 2847 },
{ "category" : "Content Server", "hits" : 1, "bytes" : 24210 },
{ "category" : "Internet Services", "hits" : 1, "bytes" : 3690 },
{ "category" : "Search Engines", "hits" : 6, "bytes" : 613036 },
{ "category" : "Search Engines", "hits" : 1, "bytes" : 2858 }
];
var res = alasql('SELECT category, sum(hits) AS hits, sum(bytes) as bytes \
FROM ? \
GROUP BY category \
ORDER BY bytes DESC',[data]);
You will get output as:
[{"category":"Search Engines","hits":13,"bytes":673684},
{"category":"Content Server","hits":3,"bytes":88930},
{"category":"Internet Services","hits":1,"bytes":3690},
{"category":"Business","hits":1,"bytes":2847}]
You can construct an array like this pretty easily by using the student names as array keys. After you have built the array, you can use array_values to convert the string keys back to numeric keys.
...
if ($rows) {
foreach ($rows as $row) {
$posts[$row['student']]['student'] = $row['student'];
$posts[$row['student']]['level'][] = $row['level'];
}
$response = array_values($posts);
echo json_encode($response, JSON_NUMERIC_CHECK);
} else { ...
This should give you the following $response:
[
{
"student": "Andreas",
"level": [4, 3]
},
{
"student": "Eivind",
"level": [4, 5]
},
{
"student": "Ole",
"level": [4, 3]
}
]
In php you can do this:
In your foreach
foreach ($rows as $row) {
$post = array();
$post["student"] = $row["student"];
$post["level"] = $row["level"];
//update our repsonse JSON data
array_push($response["posts"], $post);
}
you need to do something like this:
<?php
$response = array();
$response["posts"] = array();
$students = array("student1", "student2", "student3", "student1");
$tempArray = array();
foreach ($students as $student) {
$lvl = 1;
if(!isset($tempArray[$student])){
$tempArray[$student] = array("name" => $student, "level" => array($lvl));
}
else{
$tempArray[$student]["level"][] = $lvl;
}
}
// add it to the array
$response["posts"] = $tempArray;
// encode array
$response = json_encode($response);
echo "<br><br><br> ";
// example
// decode and make it a array for easier looping.
$response = (array)json_decode($response);
$responsePosts = (array) $response["posts"];
// foreach post
foreach($response["posts"] as $keyP => $valueP){
// convert to array same as above
$valueP = (array) $valueP;
// key that is kinda useless but made it the student name so i can easily see if it already exists
echo "key :".$keyP." <br />";
// name of the student
echo "name :".$valueP["name"]." <br />";
// all the levels
echo "levels: ";
foreach($valueP["level"] as $lvl){
echo $lvl." ";
}
echo "<br /><br />";
}
?>
This should work. Atm i use the student name as a key to see if it already exists otherwise you need to loop through all the arrays and do a "name" === $student most likely.
No push is required.

How to make custom json object with the result of a group by clause, php

I am trying to get a json object from php script. So far i have done this.
<?php
$connection=pg_connect("host=localhost port=5432 dbname=postgres user=postgres password=root") or die("Can't connect to database".pg_last_error());
$result = pg_query('SELECT * FROM playground');
$rows = array();
while($r = pg_fetch_assoc($result)) {
$rows[] = $r;
}
print json_encode(array_values(pg_fetch_all($result)));
?>
This returns the following object
[{"name":"slide","color":"blue","location":"south"},{"name":"slide","color":"green","location":"north"},{"name":"dont","color":"red","location":"west"}]
However, im trying to store them in more like....
[
{"name":"slide","values": [ "color" : ["blue","green"], "location": ["south", "north"] ]},
{"name":"dont","values" : ["color" : ["red"],"location" : ["west"] }
]
Basically, i want to group the common group by parent field values as key, and their values as the values of the json object.
But i am not able to. Would appreciate if anybody could help.
Thanks.
You could just loop through $result and create the desired array structure yourself :
while($r = pg_fetch_assoc($result)) {
if (!array_key_exists($r['name'], $rows)) {
$rows[$r['name']] = array('values' => array( 'color' => array(), 'location' => array() ));
}
if (!in_array($r['color'], $rows[$r['name']]['values']['color'])) {
$rows[$r['name']]['values']['color'][] = $r['color'];
}
if (!in_array($r['location'], $rows[$r['name']]['values']['location'])) {
$rows[$r['name']]['values']['location'][] = $r['location'];
}
}
echo json_encode($rows);
This will produce JSON on the form
{
"slide": {
"values": {
"color": [
"blue",
"green"
],
"location": [
"south",
"north"
]
}
},
"dont": {
"values": {
"color": [
"red"
],
"location": [
"west"
]
}
}
}

PHP/MYSQL/JSON: Simplify JSON for API

Hi I am trying to create an API that converts a results array from a database call into json that can be easily parsed.
Using the simple command json_encode, my JSON is a complicated, verbose mess of nested objects and arrays that is proving hard to parse on the other end.
Can anyone suggest a way to pare this down to the key information that should be provided: userid, long comment (lcom) and short comment (shcom) and how to send this as an API?
Thanks in advance for any suggestions
Here is the current JSON output produced from the following query and code:
$sql = "SELECT userid,shcom,lcom FROM comments WHERE userid = 1 LIMIT 4";
$res = mysql_query($sql) or die(mysql_error());
$comments = array();
while($row = mysql_fetch_array($res)) {
$comments[] = array('row'=>$row);
}
echo json_encode(array('comments'=>$comments));
Json output:
{
"comments": [
{
"row": {
"0": "1",
"userid": "1",
"1": "hello",
"shcom": "hello",
"2": "hellothere",
"lcom”: "hellothere"
}
},
{
"row": {
"0": "1",
"userid": "1",
“1”: ”agreed”,
"shcom”: ”agreed”,
“2”: ”agreedforonce”,
"lcom”: ”agreedforonce”
}
},
{
"row": {
"0": "1",
"userid": "1",
"1": "gohome",
"shcom”: ”gohome“,
“2”: ”gohomenow”,
"lcom: ”gohomenow”
}
},
{
"row": {
"0": "1",
"userid": "1",
"1": "getout”,
"shcom”: ”getout”,
“2”: ”getoutofhere”,
"lcom: ”getoutofhere”
}
}
]
}
You should be using mysqli rather than mysql since mysql is deprecated. Regardless, the problems in your code are happening because of two reasons. One, mysql_fetch_array does not produce the results you are expecting. Two, in your iteration you are not extracting the answers the right way. To resolve, use mysq_fetch_assoc and push only each $row to your final array.
Replace this:
while($row = mysql_fetch_array($res)) {
$comments[] = array('row'=>$row);
}
to this:
while($row = mysql_fetch_assoc($res)) {
$comments[] = $row;
}

Json_Encode php last comma

For a school project I have to display database data as a valid json file.
$result = mysqli_query($mysqli, "SELECT * FROM `csvdata`");
echo "{ \"films\" : [";
while ($row = mysqli_fetch_array($result)) {
$jsonResult = json_encode($row);
echo $jsonResult;
echo ",";
}
echo "]}";
The output i get is:
{
"films": [
{
"0": "Man on fire",
"titel": "Man on fire",
"1": "Actie",
"genre": "Actie"
},
{
"0": "Dumb and Dumberer",
"titel": "Dumb and Dumberer",
"1": "Comedy",
"genre": "Comedy"
},
{
"0": "DefQon 2014",
"titel": "DefQon 2014",
"1": "Muziek",
"genre": "Muziek"
},
]
}
Now my question is, how do I remove the last comma, I cannot find that. And all data tells the data 2 times, I also don't know how to avoid this.
Let json_encode handle the entire thing - build one array of data, and use json_encode on that.
$result = mysqli_query($mysqli, "SELECT * FROM `csvdata`");
$response = array();
$response['films'] = array();
while ($row = mysqli_fetch_array($result)) {
$response['films'][] = $row;
}
echo json_encode($response);
A good way to do this, is to not place a comma after writing every record, but instead before every record.
Then all you have to do, is add an if statement that doesn't output the comma for the very first row.

Categories