How to generate nested JSON responce using PHP and SQL - php

I have four tables, ALBUM,ARTIST,SONG,GENRES
ALBUM (ID(PK),ALBUM_NAME,ARTIST_ID(FK),GENRES_ID(FK),ALBUM_POSTER)
SONG (ID(PK),SONG_NAME,ALBUM_ID(FK),ARTIST_ID(FK),SONG_LOCATION)
ARTIST (ID(PK),ARTIST_NAME)
GENRES (ID(PK), GENRES_NAME)
I have created the bellow php file in order to create json file as "desired output" shows, but I have got "actual output" as bellow shows. All songs from all albums are included in each album "song_detail" section as the actual output shows.
php
$sql = "SELECT DISTINCT ALBUM_ID, ALBUM_NAME,ARTIST_NAME,GENRES_NAME,ALBUM_POSTER "
. "FROM ALBUM,ARTIST,SONG,GENRES "
. "WHERE ALBUM.ID=SONG.ALBUM_ID AND SONG.ARTIST_ID=ARTIST.ID AND GENRES.ID=ALBUM.GENRES_ID";
$result = $db->query($sql);
$response["albums"] = array();
if ($result->num_rows > 0)
{
while ($row = $result->fetch_assoc())
{ $album = array();
$album["album_id"] = $row["ALBUM_ID"];
$album["album_name"] = $row["ALBUM_NAME"];
$album["artist_name"] = $row["ARTIST_NAME"];
$album["genres_name"] = $row["GENRES_NAME"];
$album["album_poster"] = "http://www.".$row["ALBUM_POSTER"];
$album['song_details'] = array();
$sql2 = "SELECT*"
. " FROM SONG,ALBUM where SONG.ALBUM_ID = ALBUM.ID";
$result2 = $db->query($sql2);
while ($row2 = $result2->fetch_assoc())
{
$album['song_details'][] = array(
'songName' => $row2["SONG_NAME"],
'song_location' => "http://www.".$row2["SONG_LOCATION"]);
}
array_push($response["albums"], $album);
}
$response["success"] = 1;
}
desired output
[
{
"album_name": "Startboy",
"artist_name": "Weeknd",
"genres_name":"R&B",
"album_poster": "www.yyy.storage.x.png",
"songs_details": [{
"title": "False Alarm",
"song_location": "www././../yw.mp3"
},
{
"title": "Reminder",
"song_location": "www././../x.mp3"
}
]
},
{
"album_name": "25",
"artist_name": "Adele",
"genres_name":"",
"album_poster": "www.yyy.storage.a.png",
"songs_details": [{
"title": "Hello",
"song_location": "www././../yy.mp3"
},
{
"title": "I Miss You",
"song_location": "www././../yx.mp3"
}
]
}
]
Actual output
[
{
"album_name": "Startboy",
"artist_name": "Weeknd",
"genres_name":"R&B",
"album_poster": "www.yyy.storage.x.png",
"songs_details": [{
"title": "False Alarm",
"song_location": "www././../yw.mp3"
},
{
"title": "Reminder",
"song_location": "www././../x.mp3"
},
{
"title": "Hello",
"song_location": "www././../yy.mp3"
},
{
"title": "I Miss You",
"song_location": "www././../yx.mp3"
}]
},
{
"album_name": "25",
"artist_name": "Adele",
"genres_name":"",
"album_poster": "www.yyy.storage.a.png",
"songs_details": [{
"title": "False Alarm",
"song_location": "www././../y.mp3"
},
{
"title": "Reminder",
"song_location": "www././../x.mp3"
},
{
"title": "Hello",
"song_location": "www././../yy.mp3"
},
{
"title": "I Miss You",
"song_location": "www././../yx.mp3"
}
]
}
]

When you are selecting the songs, your SQL doesn't limit which album the tracks are from (although it does make sure they match the ALBUM)...
$sql2 = "SELECT*"
. " FROM SONG,ALBUM where SONG.ALBUM_ID = ALBUM.ID";
You need to just pick the SONG records according to the current album...
$sql2 = "SELECT * FROM SONG where ID =".$row["ALBUM_ID"];
You could use prepared statements here, but as this is using a field from another table it can be used - but not essential.

Related

Compare variable of two different array?

Here i want compare two array.
I have two tables one is CATEGORY and second is USER(in which selected multiple category is stored in this format , , , ).
but when the USER want to update their category at that time the earlier selected category should return checked 1 and which is not selected should return checked 0 and here is my code.
case 'cat':
$sql="SELECT category from nesbaty_user where user_id='".$user_id."'";
$qry_res=mysqli_query($con,$sql);
$response1 = array();
while ($array = mysqli_fetch_array($qry_res))
{
foreach (explode(',', $array['category']) as $cat)
{
$response1[]=array('category' => $cat);
$response['Selected_category'] = $response1;
}
}
$qry="SELECT cat_id,category,image_url FROM nesbaty_category";
$qry_res=mysqli_query($con,$qry);
$jsonData = array();
while ($array = mysqli_fetch_assoc($qry_res))
{
$jsonData[] = $array;
$response['category'] = $jsonData;
}
echo json_encode($response);
//echo json_encode(array('data1' =>$response1));
//
mysqli_close($con);
break;
and here is my fetched array from the database.
{
"Selected_category": [
{
"category": "5"
},
{
"category": "6"
},
{
"category": "9"
}
],
"category": [
{
"cat_id": "1",
"category": "Drug",
"image_url": "1.jpg"
},
{
"cat_id": "2",
"category": "Bars",
"image_url": "2.jpg"
},
{
"cat_id": "3",
"category": "Bars",
"image_url": "2.jpg"
},
{
"cat_id": "4",
"category": "Hair Saloon",
"image_url": "2.jpg"
}
]
}
This is for handle this same structure as You provided.
<?php
$response = [];
$sql = "SELECT category from nesbaty_user where user_id='".$user_id."'";
$qry_res = mysqli_query($con, $sql);
$selectedCategories = mysqli_fetch_array($qry_res);
$selectedCategories = explode(',', $selectedCategories['category']);
$qry = "SELECT cat_id,category,image_url FROM nesbaty_category";
$qry_res = mysqli_query($con, $qry);
while ($categories = mysqli_fetch_assoc($qry_res)) {
$categories['checked'] = (int)\in_array($categories['cat_id'], $selectedCategories);
$response[] = $categories;
}
echo json_encode($response);
mysqli_close($con);
If any error writes a comment, I'll fix it.

Store object into array and group all array with the same value in PHP

I'm working on array right now and I need to arrange this based on value.
{
"data": {
"id": 2,
"title": "second evaluation form",
"emp_position": "System Architecture",
"rating": 5,
"segments": [
{
"segment_name": "Job Role ",
"question": "How old are you?"
},
{
"segment_name": "360 Segments",
"question": "What is your food?"
},
{
"segment_name": "360 Segments",
"question": "sample question"
},
]
}
}
What I need to do is to store this object into array and group all question based on segment_name like this:
{
"data":[
{
"id": 2,
"title": "second evaluation form",
"emp_position": "System Architecture",
"rating": 5,
"segments": [
{
"segment_name": "Job Role "
"question_collection": [
{
"id": 4,
"question": "How old are you?"
}
]
},
{
"segment_name": "360 Segments",
"question_collection":[
{
"id": 1,
"question": "What is your food?"
},
{
"id": 2,
"question": "sample question"
}
]
},
]
}
]
}
And this is what I've tried to do:
$array_value =[];
foreach ($query AS $key => &$data) {
$array_value['id'] = $data['id'];
$array_value['title'] = $data['title'];
$array_value['emp_position'] = $data['position'];
$array_value['rating'] = $data['rating_count'];
if ( is_array($data) ) {
$array_value['segments'][$key]['segment_name'] = $data['segment'];
$array_value['segments'][$key]['question'] = $data['question'];
}
}
Collection function might help you find your solution.
$json = '{"data":{"id":2,"title":"second evaluation form","emp_position":"System Architecture","rating":5,"segments":[{"segment_name":"Job Role ","question":"How old are you?"},{"segment_name":"360 Segments","question":"What is your food?"},{"segment_name":"360 Segments","question":"sample question"}]}}';
$array = json_decode($json, true);
$coll = collect($array['data']['segments']);
$coll = $coll->groupBy('segment_name');
dump($coll);
Hope this helps you.Let me know if any problem
Do it like below:-
<?php
$json = '{
"data": {
"id": 2,
"title": "second evaluation form",
"emp_position": "System Architecture",
"rating": 5,
"segments": [
{
"segment_name": "Job Role ",
"id": 4,
"question": "How old are you?"
},
{
"segment_name": "360 Segments",
"id": 1,
"question": "What is your food?"
},
{
"segment_name": "360 Segments",
"id": 2,
"question": "sample question"
}
]
}
}
';
$query = json_decode($json,true);
$segment_array = [];
foreach($query['data']['segments'] as $arr){
$segment_array[$arr['segment_name']]['segment_name'] = $arr['segment_name'];
$segment_array[$arr['segment_name']]['question_collection'][] = ['id'=>$arr['id'],'question'=>$arr['question']] ;
}
$query['data']['segments'] = array_values($segment_array);
echo json_encode($query,JSON_PRETTY_PRINT);
OUTPUT:- https://eval.in/902194
Try this solution, You can loop by array and group all keys
$json = '{
"data": {
"id": 2,
"title": "second evaluation form",
"emp_position": "System Architecture",
"rating": 5,
"segments": [
{
"segment_name": "Job Role ",
"question": "How old are you?"
},
{
"segment_name": "360 Segments",
"question": "What is your food?"
},
{
"segment_name": "360 Segments",
"question": "sample question"
}
]
}
}';
$data = json_decode($json,true);
$segments = $data['data']['segments'];
$new_segemnts = array();
foreach($segments as $segemnt)
{
$key = $segemnt['segment_name'];
$new_segemnts[$key]['segment_name']=$segemnt['segment_name'];
$new_segemnts[$key]['question_collection'][]=array("question"=>$segemnt['question']);
}
$data['data']['segments'] = array_values($new_segemnts);
echo json_encode($data,JSON_PRETTY_PRINT);
DEMO
Here try my answer. I've just editted your existing code so you won't confuse that much. Nothing much to explain here. I included some explaination in my comment.
CODE
$array_value =[];
foreach ($query AS $key => &$data) {
$array_value['id'] = $data['id'];
$array_value['title'] = $data['title'];
$array_value['emp_position'] = $data['position'];
$array_value['rating'] = $data['rating_count'];
if ( is_array($data) ) {
// Check if segment is already added
$has_segment = false;
$segment_key = null;
foreach($array_value['segments'] as $key2 => $val){
//If segment is already added get the key
if($val['segment_name'] == $data['segment']){
$segment_key = $key2;
$has_segment = true;
break;
}
}
// if segment does not exists. create a new array for new segment
if(!$has_segment){
$array_value['segments'] = array();
}
// If new segment, get the index
$segment_key = count($array_value['segments']) - 1;
// If new segment, create segment and question collection array
if(!array_key_exists('question_collection', $array_value['segments'][$segment_key])){
$array_value['segments'][$segment_key]['segment_name'] = $data['segment'];
$array_value['segments'][$segment_key]['question_collection'] = array();
}
//Add the id for question collectiona rray
$array_value['segments'][$segment_key]['question_collection'][] = array(
"id" => $data['question_id'],
"question" => $data['question']
);
}
}

Sort JSON by ID

I have following JSON file:
[{
"id": 9,
"title": "Birthday",
"description": "Debut Party",
"start": "2017-07-25T15:01",
"end": "2017-08-03T00:01",
"url": "https:\/\/bd.com"
}, {
"id": 11,
"title": "Anniversary",
"description": "First Ann",
"start": "2017-06-28T15:00",
"end": "2017-07-08T02:58",
"url": "https:\/\/anniversary.com\/"
}, {
"id": 5,
"title": "Anniversary",
"description": "First Ann",
"start": "2017-06-28T15:00",
"end": "2017-07-08T02:58",
"url": "https:\/\/anniversary.com\/"
}]
I want them to be sorted by id like 5,9,11 using PHP. How Can I do that?
First decode the JSON
$array = json_decode($json,true);
and then use usort to sort by id or something else.
function sortById($a, $b) {
return $b->id - $a->id;
}
usort($array,"sortById");
SELECT * FROM test ORDER BY `id` DESC;
use this query in you php file.
example :
function getPosts()
{
$connection = mysqli_connect("localhost", "root", "", DatabaseManager::DATABASE_NAME);
$sqlQuery = "SELECT * FROM posts order by 'id' desc;";
$result = $connection->query($sqlQuery);
$postsArray = array();
if ($result->num_rows > 0) {
for ($i = 0; $i < $result->num_rows; $i++) {
$postsArray[$i] = $result->fetch_assoc();
}
}
echo json_encode($postsArray);
}

How to combine multiple SQL queries into one to output as JSON in PHP code?

I currently have the following table set up:
StartTime EndTime Performer Event Day Location
-----------------------------------------------------
1:00pm 2:00pm Test Test 0 1
11:00pm 12:00am Test Test 0 0
2:00pm 2:30pm Test Test 1 0
11:00pm 12:00am Test Test 2 1
The JSON output looks something like this:
{
"day0": {
"item1": {
"StartTime": "1:00pm",
"EndTime": "2:00pm",
"Performer": "Test",
"Event": "Test",
"Location": 1
},
"item2": {
"StartTime": "11:00pm",
"EndTime": "12:00am",
"Performer": "Test",
"Event": "Test",
"Location": 0
}
},
"day1": {
"item1": {
"StartTime": "2:00pm",
"EndTime": "2:30pm",
"Performer": "Test",
"Event": "Test",
"Location": 0
}
},
"day2": {
"item1": {
"StartTime": "11:00pm",
"EndTime": "12:00am",
"Performer": "Test",
"Event": "Test",
"Location": 1
}
}
}
Since I'm still learning PHP, I wrote some sloppy code by making 3 queries to the database, each time selecting all data where the day was 1, 2, and 3.
Here's an example of code for fetching data for day=0, which is repeated for day=1 and day=2:
echo '{ "day0" : {';
$sql = "select * from table WHERE day = 0";
$result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection));
$jsonData = array();
$rowCount = $result->num_rows;
$index = 1;
while($row =mysqli_fetch_assoc($result))
{
echo '"item'.$index.'":';
echo json_encode(array("StartTime" => $row['StartTime'], "EndTime" => $row['EndTime'], "Performer" => $row['Performer'], "Event" => $row['Event'], "Location" => intval($row['Location'])));
if ($rowCount != $index)
{
echo ',';
}
++$index;
}
echo ' }';
// Repeated code for day=1
// Repeated code for day=2
echo ' }';
I feel as though this can be achieved with just one query, but being that I'm new, I'm not sure how to implement it.
I started to do something like this:
$sql = "select * from table";
$result = mysqli_query($connection, $sql) or die("Error in Selecting " . mysqli_error($connection));
$jsonData = array();
$numOfRows = $result->num_rows;
$count = 1;
while($row = mysqli_fetch_assoc($result))
{
$outerIndex = 'day'.$row['day'];
if ($row['day'] == '1')
{
// Do something, not sure
}
if ( !isset( $jsonData[$outerIndex] ) )
{
$innerIndex = 'item'.$count.'';
$jsonData[$outerIndex][$innerIndex] = $row;
}
++$count;
}
echo json_encode($jsonData);
However, I just got stuck, and not really sure how to approach it further.
SQL:
$sql = "SELECT * FROM table ORDER BY Day";
Further down on code:
$result_object = [];
$item = 1;
while ($row = $result->fetch_assoc()) {
if(isset($result_object['day'.$row['Day']]))
{
$result_object['day'.$row['Day']]['item'.$item] = $row;
$item++;
}
else
{
$result_object['day'.$row['Day']]['item1'] = $row;
$item = 2;
}
}
You can then output it with:
echo json_encode($result_object, JSON_PRETTY_PRINT); //JSON_PRETTTY_PRINT is not necessary...
You may disagree with me, but I don't think indexing items with item0, item1 and so on.... or day0, day1 ... is a GOOD idea. I personally prefer that the looping through the result would be:
while ($row = $result->fetch_assoc()) {
if(isset($result_object[$row['Day']]))
{
$result_object[$row['Day']]->items[] = $row;
}
else
{
$result_object[$row['Day']] = (object)['day'=>$row['Day'], 'items'=>[$row]];
}
}
In this case, the result would be an array of objects. ie:
[
{
"day": "0",
"items": [
{
"StartTime": "07:23:56",
"EndTime": "17:24:04",
"Performer": "Performer1",
"Event": "Event1",
"Day": "0",
"Location": "1"
},
{
"StartTime": "09:24:30",
"EndTime": "01:04:37",
"Performer": "Performer2",
"Event": "Event2",
"Day": "0",
"Location": "1"
}
]
},
{
"day": "1",
"items": [
{
"StartTime": "10:25:22",
"EndTime": "11:25:29",
"Performer": "Performer2",
"Event": "Event3",
"Day": "1",
"Location": "2"
}
]
},
{
"day": "2",
"items": [
{
"StartTime": "12:26:08",
"EndTime": "13:26:12",
"Performer": "Performer3",
"Event": "Event4",
"Day": "2",
"Location": "1"
}
]
}
]
The reason: you can easily iterate through each values(an array) in whatever language you're going to use.

JSON array in array from SQL database using PHP

I have the following code:
$retarray = array();
$hoursarray = array();
$res = $this->mysqli->query("SELECT id, title, groupby FROM scheduler_activity WHERE gewerbe = '$this->gewerbe'");
while($row = $res->fetch_object()) {
$foo = $this->mysqli->query("SELECT dow, start, end FROM scheduler_businesshours WHERE activity = '$row->id'");
while($hours = $foo->fetch_object()){
$hoursarray[] = $hours;
}
$retarray[] = $row;
$retarray["businessHours"] = $hoursarray;
}
return $retarray;
And the following JSON output:
{
"0": {
"id": "1",
"title": "Spinning",
"groupby": "Trainingsgruppe"
},
"businessHours": [{
"dow": "[1,2,3]",
"start": "17:00:00",
"end": "18:00:00"
}, {
"dow": "[4,5]",
"start": "17:30:00",
"end": "18:30:00"
}],
"1": {
"id": "2",
"title": "Massage",
"groupby": "Trainingsgruppe"
},
"2": {
"id": "3",
"title": "Yoga",
"groupby": "Trainingsgruppe"
},
"3": {
"id": "4",
"title": "Dance Academy",
"groupby": "Trainingsgruppe"
}
}
So far it looks correct but I need to get rid of the leading numbers like 0, 1, 2, 3
That it will look like this plus the businessHours:
[{
"id": "1",
"title": "Spinning",
"groupby": "Trainingsgruppe"
}, {
"id": "2",
"title": "Massage",
"groupby": "Trainingsgruppe"
}, {
"id": "3",
"title": "Yoga",
"groupby": "Trainingsgruppe"
}, {
"id": "4",
"title": "Dance Academy",
"groupby": "Trainingsgruppe"
}]
What did I do wrong there?
Thank you!
As I understood about your code, we get business hour for each activity, so it's just a small change at line 10:
$retarray = array();
$hoursarray = array();
$res = $this->mysqli->query("SELECT id, title, groupby FROM scheduler_activity WHERE gewerbe = '$this->gewerbe'");
while($row = $res->fetch_object()) {
$foo = $this->mysqli->query("SELECT dow, start, end FROM scheduler_businesshours WHERE activity = '$row->id'");
while($hours = $foo->fetch_object()){
$hoursarray[] = $hours;
}
$row["businessHours"] = $hoursarray; // Change to this, swap line 10 & 11
$retarray[] = $row;
}
return $retarray;
Hope this helps.
You add two keys. One key is numeric the second is businessHours.
$retarray[] = $row;
$retarray["businessHours"] = $hoursarray;
For instance you can add it businessHours to $row
$row["businessHours"] = $hoursarray;
$retarray[] = $row;
Have you try array_values($array)?
$retarray = array();
$hoursarray = array();
$res = $this->mysqli->query("SELECT id, title, groupby FROM scheduler_activity WHERE gewerbe = '$this->gewerbe'");
while($row = $res->fetch_object()) {
$foo = $this->mysqli->query("SELECT dow, start, end FROM scheduler_businesshours WHERE activity = '$row->id'");
while($hours = $foo->fetch_object()){
$hoursarray[] = $hours;
}
$retarray[] = $row;
$retarray["businessHours"] = $hoursarray;
}
return array_values($retarray);

Categories