Multiple MySQL table to json_encode - php

I have 3 different tables in my database called consoleConsole, consoleModel, and consoleGame. Then what I want to do is that each console will have a loop inside for its models, and each models will have another loop inside for its games like this:
[
{
"Console":"PlayStation",
"Information":[
{
"Model":"PlayStation 3",
"Title":[
{
"Game":"007 Legends",
"Publisher":"Electronic Arts"
},
{
"Game":"Ace Combat: Assault Horizon",
"Publisher":"Namco"
}
]
},
{
"Model":"PlayStation 2",
"Title":[
{
"Game":"007: Agent of Fire",
"Publisher":"Electronic Arts"
},
{
"Game":"Ace Combat 4: Shattered Skies",
"Publisher":"Namco"
}
]
},
{
"Model":"PlayStation 1",
"Title":[
{
"Game":"007 Racing",
"Publisher":"Electronic Arts"
},
{
"Game":"Ace Combat",
"Publisher":"Namco"
}
]
}
]
},
{
"Console":"Wii",
"Information":[
{
"Model":"Wii",
"Title":[
{
"Game":"007: Quantum of Solace",
"Publisher":"Activision"
},
{
"Game":"AC/DC Live: Rock Band Track Rack",
"Publisher":"MTV Games"
}
]
}
]
},
{
"Console":"Xbox",
"Information":[
{
"Model":"Xbox",
"Title":[
{
"Game":"AFL",
"Publisher":"Acclaim"
},
{
"Game":"American Chopper",
"Publisher":"Activision"
}
]
},
{
"Model":"Xbox 360",
"Title":[
{
"Game":"AFL Live",
"Publisher":"Electronic Arts"
},
{
"Game":"Akai Katana Shin",
"Publisher":"Cave"
}
]
}
]
}
]
But sadly, I was not using my database with this one but instead I just wrote it straight in a php file.
EDIT
Anyways, moving on. I have modified my code and ended up like this.
<?PHP
$consoleQuery = "SELECT * ".
"FROM consoleConsole ".
"JOIN consoleModel ".
"ON consoleConsole.consoleId = consoleModel.consoleId ".
"JOIN consoleGame ".
"ON consoleModel.modelId = consoleGame.gameId";
$consoleResult = mysql_query($consoleQuery);
$consoleFields = array_fill_keys(array(
'consoleName',
), null);
$modelFields = array_fill_keys(array(
'modelName',
), null);
$console = array();
$rowConsole = array();
while ($rowConsole = mysql_fetch_assoc($consoleResult)) {
$consoleId = $rowConsole['consoleId'];
$modelId = $row['modelId'];
if (isset($console[$consoleId]['Information'])) {
$console[$consoleId]['Information'][] = array_intersect_key($rowConsole, $modelFields);
}
else {
$console[$consoleId] = array_intersect_key($rowConsole, $consoleFields);
$console[$consoleId]['Information'] = array(array_intersect_key($rowConsole, $modelFields));
}
}
$console = array_values($console);
echo json_encode($console);
?>
I was able to produce an output but it doesn't look like the output above.
[
{
"consoleName": "PlayStation",
"Information": [
{
"modelName": "PlayStation"
},
{
"modelName": "PlayStation 2"
},
{
"modelName": "PlayStation 3"
},
{
"modelName": "PlayStation 3"
}
]
},
{
"consoleName": "Wii",
"Information": [
{
"modelName": "Wii"
},
{
"modelName": "Wii"
}
]
},
{
"consoleName": "Xbox",
"Information": [
{
"modelName": "Xbox"
},
{
"modelName": "Xbox 360"
}
]
}
]
Their relations:
What my problem is right now, I can't add the Title of the each Game.

Ok so I have written up your solution. You have to be sure that the order by is included there because it assumes that you are ordering them with there items together. I also didnt know how your publisher was stored so I separated that out into a separate table (this will allow you to then get items by just there publisher as well), which is now 4 joins. Also on another note I have updated it to do inner joins as well. This way you will not get empty results for consoles that don't have any games assigned to them. If you want these you could simply change the joins so that it would give you those results as well. Let me know if this helps
//get all of the information
$query = '
SELECT c.consoleId,c.consoleName,m.modelId,m.modelName,g.gameId,g.gameName,p.publisherId,p.publisherName
FROM `consoleconsole` c
INNER JOIN `consolemodel` m ON c.consoleId=m.consoleId
INNER JOIN `consolegame` g ON m.modelId=g.modelId
INNER JOIN `consolepublisher` p ON g.publisherId = p.publisherId
ORDER BY c.consoleName, m.modelName, g.gameName
';
//get the results
$result = mysql_query($query);
//setup array to hold information
$consoles = array();
//setup holders for the different types so that we can filter out the data
$consoleId = 0;
$modelId = 0;
//setup to hold our current index
$consoleIndex = -1;
$modelIndex = -1;
//go through the rows
while($row = mysql_fetch_assoc($result)){
if($consoleId != $row['consoleId']){
$consoleIndex++;
$modelIndex = -1;
$consoleId = $row['consoleId'];
//add the console
$consoles[$consoleIndex]['console'] = $row['consoleName'];
//setup the information array
$consoles[$consoleIndex]['information'] = array();
}
if($modelId != $row['modelId']){
$modelIndex++;
$modelId = $row['modelId'];
//add the model to the console
$consoles[$consoleIndex]['information'][$modelIndex]['model'] = $row['modelName'];
//setup the title array
$consoles[$consoleIndex]['information'][$modelIndex]['title'] = array();
}
//add the game to the current console and model
$consoles[$consoleIndex]['information'][$modelIndex]['title'][] = array(
'game' => $row['gameName'],
'publisher' => $row['publisherName']
);
}
echo json_encode($consoles);

Since you are using php function to encode json , it will give you the json in its default format. what you have to do is create your own function using string manipulation to get desired result.

Related

Getting Data from MySQL and display objects inside object for PHP Rest-API

I am currently trying to create a Rest-API for two MySQL-Tables.
There is a table "Course-Type" and one with "Courses". The "Courses"-Table contains a Foreign-Key for the Course-Types.
When calling the API using the SQL-Code below i will get multiple Objects with the same "Course-Type".
How can i add all items with the same Course-Type inside the same Course-Type-Object to fetch using the API?
My SQL-Code:
$query = "SELECT * FROM Ausbildung, Ausbildungsart WHERE Ausbildung.ART = Ausbildungsart.ID;";
Currently i am getting following Output when hitting the API:
{
"status":"true",
"target":"database",
"method":"fetch-courses",
"courses":[
{
"SKILLID":"7797701-901",
"ART":"1",
"BESCHREIBUNG":"simple course",
"ID":"1",
"AUSBILDUNGSBESCHREIBUNG":"type1"
},
{
"SKILLID":"7797701-902",
"ART":"2",
"BESCHREIBUNG":"another simple course",
"ID":"2",
"AUSBILDUNGSBESCHREIBUNG":"type2"
},
{
"SKILLID":"7797800-401",
"ART":"2",
"BESCHREIBUNG":"latest simple course",
"ID":"2",
"AUSBILDUNGSBESCHREIBUNG":"type2"
}
]
}
I am trying to get the following Output:
{
"status":"true",
"target":"database",
"method":"fetch-courses",
"courses":[
{
"ID":"1",
"AUSBILDUNGSBESCHREIBUNG":"type1",
"KURSE":[
{
"SKILLID":"7797701-901",
"BESCHREIBUNG":"simple course"
}
]
},
{
"ID":"2",
"AUSBILDUNGSBESCHREIBUNG":"type2",
"KURSE":[
{
"SKILLID":"7797701-902",
"BESCHREIBUNG":"another simple course"
},
{
"SKILLID":"7797800-401",
"BESCHREIBUNG":"latest simple course"
}
]
}
]
}
My Current Approach is to use a foreach-Loop like this below to assign the value to the array:
$query = "SELECT * FROM Ausbildungsart;";
$result = mysqli_query($con,$query);
$courseCategories = mysqli_fetch_all($result,MYSQLI_ASSOC);
foreach ($courseCategories as &$category) {
$query = "SELECT * FROM Ausbildung WHERE Ausbildung.ART = $category['ID'];";
$response = mysqli_fetch_all(mysqli_query($con, $query), MYSQLI_ASSOC);
array_push($category, $response);
}
//$query = "SELECT * FROM Ausbildung, Ausbildungsart WHERE Ausbildung.ART = Ausbildungsart.ID;";
$response["status"] = "true";
$response["target"] = "Database";
$response["method"] = "fetch-courses";
$response["courses"] = $courseCategories;
echo json_encode($response); exit;

Nested array response in JSON returning only last row from Mysql table

My database have three tables(category,catgory_details,questions), Now one category have many questions. I want to have a JSON response like this:
[
{
"category": "Accountant",
"deatils": {
"video_link": "https://www.youtube.com/",
"form_link": "https://docs.google.com/forms/u/0/",
"questions": [
"Who is your idiol",
"What is ur name?"
]
}
},
{
"category": "Actuary",
"deatils": {
"video_link": "https://www.youtube.com/",
"form_link": "https://docs.google.com/forms/u/0/",
"questions": [
"What is great?",
"What is ur name?"
]
}
}
]
but my code is returning only one row from questions tables like this:
[
{
"category": "Accountant",
"deatils": {
"video_link": "https://www.youtube.com/",
"form_link": "https://docs.google.com/forms/u/0/",
"questions": [
"Who is your idiol"
]
}
},
{
"category": "Actuary",
"deatils": {
"video_link": "https://www.youtube.com/",
"form_link": "https://docs.google.com/forms/u/0/",
"questions": [
"What is great?"
]
}
}
]
Following is my php code:
<?php
header("Content-Type: application/json");
include('db.php');
$result = mysqli_query($conn,"SELECT * FROM categories ORDER BY id ASC");
$json_response = array();
while ($row = mysqli_fetch_array($result))
{
$row_array = array();
$row_array['category'] = $row['category'];
$id = $row['id'];
$detail_query = mysqli_query($conn,"SELECT * FROM category_details WHERE category_id=$id");
$question_query = mysqli_query($conn,"SELECT * FROM questions WHERE category_id=$id");
if($question_query->num_rows !== 0){
while ($detail_fetch = mysqli_fetch_array($detail_query))
{
while ($question_fetch = mysqli_fetch_array($question_query))
{
$row_array['deatils'] = array(
'video_link' => $detail_fetch['video_link'],
'form_link' => $detail_fetch['form_link'],
'questions' => [$question_fetch['question'][1],$question_fetch['question'][2]],
);
}
}
}
else{
while ($detail_fetch = mysqli_fetch_array($detail_query))
{
$myid = $detail_fetch['id'];
$row_array['deatils'] = array(
'video_link' => $detail_fetch['video_link'],
'form_link' => $detail_fetch['form_link'],
);
}
}
array_push($json_response, $row_array);
}
echo json_encode($json_response);
?>
What changes should I make in order to get my required JSON response?
Instead of building $row_array['deatils'] within the question_fetch loop, you should do it within the detail_fetch loop, and then populate just the questions sub-array within the question_fetch loop
while ($detail_fetch = mysqli_fetch_array($detail_query))
{
$row_array['deatils'] = array(
'video_link' => $detail_fetch['video_link'],
'form_link' => $detail_fetch['form_link'],
'questions' => array(),
);
while ($question_fetch = mysqli_fetch_array($question_query))
{
$row_array['deatils']['questions'][] = $question_fetch['question'];
}
}
Try to change :
'questions' => [$question_fetch['question'][1],$question_fetch['question'][2]],
to :
'questions' => $question_fetch['question'],
So you will have the full array of questions included in the response.

PHP with Json + SQL

I'm having trouble correctly display, in JSON, a result originated from two tables in my database.
The situation is this: I have orders in a table (A) and the products these orders in another table (B).
My code:
$sqlcode2 = mysql_query("Select a.numero as numOrc, a.nomeclie, a.valortotal, a.formapagto, a.emissao, b.codprod, b.qtdade, b.valorunit, b.tipopreco from orcamento a, prodorc b");
$jsonObj= array();
if($something == 'all')
{
while($result=mysql_fetch_object($sqlcode2))
{
$jsonObj[] = $result;
$teste= array('pedidos' => $jsonObj);
}
}
$final_res =json_encode($teste);
echo $final_res;
The JSON result is like this:
{
"pedidos": [
{
"numOrc": "1",
"nomeclie": "CONSUMIDOR",
"valortotal": "2.077,20",
"formapagto": "2",
"emissao": "2013-02-15 16:09:11",
"codprod": "4775",
"qtdade": "1",
"valorunit": "500,00",
"tipopreco": "B"
},
{
"numOrc": "2",
"nomeclie": "MARCELO AUGUSTO BOTURA",
"valortotal": "2.077,20",
"formapagto": "2",
"emissao": "2013-02-15 16:21:56",
"codprod": "4775",
"qtdade": "1",
"valorunit": "500,00",
"tipopreco": "B"
}
]
}
As you can see, the result is only one product in each order. I needed the result to be as below (Detalhes TAG):
{
"pedidos": [
{
"numOrc": "2",
"nomeclie": "MARCELO AUGUSTO BOTURA",
"valortotal": "2.077,20",
"formapagto": "2",
"emissao": "2013-02-15 16:21:56",
"Detalhes":
[
{
"codprod": "4775",
"qtdade": "1",
"valorunit": "500,00",
"tipopreco": "B"
},
{
"codprod": "5555",
"qtdade": "3",
"valorunit": "800,00",
"tipopreco": "A"
}
]
}
]
}
A quick example of what FirstOne suggests would look like this. See how the orders are selected first and then a 2nd query is used to gather additional information about that order.
$sqlcode2 = mysql_query("Select a.numero as numOrc, a.nomeclie, a.valortotal, a.formapagto, a.emissao from orcamento a");
$jsonObj= array();
if($something == 'all')
{
while($result=mysql_fetch_object($sqlcode2))
{
$sqlcode3 = mysql_query("Select b.codprod, b.qtdade, b.valorunit, b.tipopreco
FROM prodorc b WHERE b.numOrc = " . $result->numOrc);
$Detalhes = array();
while($orderResult=mysql_fetch_object($sqlcode3))
{
$Detalhes[] = $orderResult;
}
$result->Detalhes = $Detalhes;
$jsonObj[] = $result;
}
}
$teste= array('pedidos' => $jsonObj);
$final_res =json_encode($teste);
echo $final_res;

MySQL to nested JSON

This is almost exactly what I want, but that question hasn't been answered and it's been a year. I've managed to get close, I think, but numbers are being printed as keys. In my example it shows up on line 47, but it is repeated for every "course_name" in the actual file.
[
{
"school_name": "Projects",
"terms": [
{
"term_name":"category_name#1",
"departments": [
{
"department_name":"sub_category_name1",
"department_code":"category code text here",
"courses":[
{
"course_name": "project1",
"course_code":"project 1 code text goes here",
"sections":[
{
"section_code":"mike",
"unique_id":"xxx#mail.com"
},
{
"section_code":"dan",
"unique_id":"xxx#gmail.com"
}
]
},
{
"course_name": "project2",
"course_code":"project 2 code text goes here",
"sections":[
{
"section_code":"steve",
"unique_id":"xxx#mail.com"
},
{
"section_code":"chris",
"unique_id":"xxx#gmail.com"
}
]
}
]
},
{
"department_name": "sub_category_name2",
"department_code":"sub category description text goes here..",
"courses": {
-->>> "69": {
"course_name": "project3",
"course_code":"project3 code text goes here ",
"sections":[
{
"section_code":"Alex",
"unique_id":"xxx#gmail.com"
}
]
}
}
}
]
}
]
}
]
Here is the query I am using and an example of data being returned.
SELECT school_name, term_name, department_name, department_code, course_code, course_name, section_code, magento_course_id
FROM schools INNER JOIN term_names ON schools.id=term_names.school_id INNER JOIN departments ON schools.id=departments.school_id INNER JOIN
adoptions ON departments.id=adoptions.department_id
"UCA-2" "SPRING 2013" "ACCOUNTING" "ACCT" "3315" "COST ACCOUNTING" "10258" 10311
What I have is being generated with this code.
$row_array = array();
$terms = array();
$departments = array();
$courses = array();
$h = 0;
$i = 0;
$j = 0;
while ($row = mysqli_fetch_assoc($fetch)) {
$row_array[$row['school_name']]['school_name'] = $row['school_name'];
$akey = array_search($row['term_name'], $terms);
if ($akey === FALSE) {
$m = $h++;
$terms[] = $row['term_name'];
$row_array[$row['school_name']]['terms'][$m]['term_name'] = $row['term_name'];
} else {
$m = $akey;
}
$key = array_search($row['department_code'], $departments);
if ($key === FALSE) {
$k = $i++;
$departments[] = $row['department_code'];
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['department_name'] = $row['department_name'];
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['department_code'] = $row['department_code'];
} else {
$k = $key;
}
$skey = array_search($row['course_code'], $courses);
if ($skey === FALSE) {
$l = $j++;
$courses[] = $row['course_code'];
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['courses'][$l]['course_name'] = $row['course_name'];
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['courses'][$l]['course_code'] = $row['course_code'];
} else {
$l = $skey;
}
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['courses'][$l]['sections'][] = array('section_code' => $row['section_code'], 'unique_id' => $row['magento_course_id']);
}
How do I generate this JSON without those numbers showing up?
I think you have some key & encoding problems. Too much key usage, excessive loops in your code. Maybe you should tidy your sql query.
Since you are setting keys for courses, JSON shows it.
Try removing the key after "['courses']" in your last line such as;
Change ['courses'][$l] to ['courses'][]
At the end, encode the array for JSON.
$result = json_encode($result);

Recursive function in async tree in php gets with "Fatal error: Allowed memory size of 134217728"

i have tried to do an async tree but when i call a function inside the function she get me an memory error. I have read many things how to change the limit of the php memory to run that and i tried that and it doesn't result. But what i realy want is a way to "stop" the function, to not call that infinitely times. Can anyone help me?
function treeview()
{
$i = 0;
$result = array();
$rs = mysql_query("select * from dados3 where nivel = 1");
while($row = mysql_fetch_array($rs))
{
$node = array();
$node['id'] = $row['id'];
$node['text'] = $row['descricao'];
$node['state'] = 'closed';
$node['children'] = has_child($row['id']);
array_push($result, $node);
}
echo json_encode($result);
}
function has_child($id){
$result2 = array();
$node_2 = array();
$rs = mysql_query("select * from dados3 where id_nivel_superior=$id");
$row = mysql_fetch_array($rs);
$node_2['text'] = $row['descricao'];
$node_2['state'] = 'closed';
$node_2['children'] = has_child($id);
array_push($result2, $node_2);
return $result2;
}
I tried the above way and that returns me all the children null and at level 3 repeats me the level 1. What you think it can be wrong?
function treeview()
{
$i = 0;
$result = array();
$rs = mysql_query("select * from dados3 where nivel = 1");
while($row = mysql_fetch_array($rs))
{
$node = array();
$node['id'] = $row['id'];
$node['text'] = $row['descricao'];
$node['state'] = 'closed';
$node['children'] = has_child($row['id']);
array_push($result, $node);
}
echo json_encode($result);
}
function has_child($id){
$result2 = array();
$node_2 = array();
$rs = mysql_query("select * from dados3 where id_nivel_superior=$id");
while($row = mysql_fetch_array($rs))
{
$node_2['text'] = $row['descricao'];
$node_2['state'] = 'closed';
$node_2['children'] = has_child($row['id']);
array_push($result2, $node_2);
return $result2;
}
}
Here at the image you can see the database structure anda data:
image of database
I have already put the return out of the loop but the json that returns me it's with the cildren all null. And at level 4 (where i want to show something) it continuos repeatedly all the levels again.
[{"id":"1","text":"1 - Cat.","state":"closed","children":[{"text":"1.1 - Sub.","state":"closed","children":[]},{"text":"1.2 - Sub.","state":"closed","children":[]},{"text":"1.3 - Sub.","state":"closed","children":[]}]},{"id":"2","text":"2 - Cat.","state":"closed","children":[{"text":"2.1 - Sub.","state":"closed","children":[{"text":"2.1.1 - Sub_sub","state":"closed","children":[{"text":"Faq 1 - categoria 1","state":"closed","children":[]}]}]},{"text":"2.2 - Sub.","state":"closed","children":[]},{"text":"2.3 - Sub.","state":"closed","children":[]}]},{"id":"4","text":"3- Cat.","state":"closed","children":[{"text":"3.1 - Sub.","state":"closed","children":[]},{"text":"3.2 - Sub.","state":"closed","children":[]},{"text":"3.3 - Sub.","state":"closed","children":[]}]},{"id":"5","text":"4 - Cat.","state":"closed","children":[{"text":"4.1 - Sub.","state":"closed","children":[]},{"text":"4.2 - Sub.","state":"closed","children":[]},{"text":"4.3 - Sub.","state":"closed","children":[]}]}]
If you can help me understand why the children doesn't appears i will appreciate.
Best regards.
It looks like the problem is your recursive call to has_child() is passing in $id, i.e. the parameter originally passed to the function. So, what's happening is because the function is being called with the same parameter every time, it will recursively call itself endlessly.
I suspect the line
$node_2['children'] = has_child($id);
should actually read
$node_2['children'] = has_child($row['id']);
Also, I suspect you probably want a loop in has_child() as well, in the same way as in treeview() otherwise you'll only get the first item at each level of the tree.
EDIT
Actually, sorry, I may have misunderstood what's going on here. Earlier I assumed that "id_nivel_superior" was the parent item's ID, but am I right in saying that actually that's the parent's level within the tree? If so, is there something that does contain the parent item's ID, as that's the column your SQL statement in has_child() needs to use. It might help if you could post your table structure and a sample of your data.
Also, your return statement in has_child() needs to be outside the loop.
OK, to answer your latest edit, I might be missing something here, but it looks like the JSON output you've posted is correct according to the data you have. Its a bit tricky to read on one line, but if you run it through the formatter at http://jsonformatter.curiousconcept.com/ you'll see this is what it looks like:
[
{
"id":"1",
"text":"1 - Cat.",
"state":"closed",
"children":[
{
"text":"1.1 - Sub.",
"state":"closed",
"children":[
]
},
{
"text":"1.2 - Sub.",
"state":"closed",
"children":[
]
},
{
"text":"1.3 - Sub.",
"state":"closed",
"children":[
]
}
]
},
{
"id":"2",
"text":"2 - Cat.",
"state":"closed",
"children":[
{
"text":"2.1 - Sub.",
"state":"closed",
"children":[
{
"text":"2.1.1 - Sub_sub",
"state":"closed",
"children":[
{
"text":"Faq 1 - categoria 1",
"state":"closed",
"children":[
]
}
]
}
]
},
{
"text":"2.2 - Sub.",
"state":"closed",
"children":[
]
},
{
"text":"2.3 - Sub.",
"state":"closed",
"children":[
]
}
]
},
{
"id":"4",
"text":"3- Cat.",
"state":"closed",
"children":[
{
"text":"3.1 - Sub.",
"state":"closed",
"children":[
]
},
{
"text":"3.2 - Sub.",
"state":"closed",
"children":[
]
},
{
"text":"3.3 - Sub.",
"state":"closed",
"children":[
]
}
]
},
{
"id":"5",
"text":"4 - Cat.",
"state":"closed",
"children":[
{
"text":"4.1 - Sub.",
"state":"closed",
"children":[
]
},
{
"text":"4.2 - Sub.",
"state":"closed",
"children":[
]
},
{
"text":"4.3 - Sub.",
"state":"closed",
"children":[
]
}
]
}
]
which as far as I can tell matches the database. If there's something not right about this then can you please let me know what output you're expecting to get?

Categories