Recently I had some experience with converting mysql query results into json for a quiz system. Query results contain set of questions and related anwsers to them. The implemented procedure aims to put those questions and answers into multidimensional array and then convert it into json to build quiz db. I've ready to use JS procedure (quiz module) that works with below mentioned JSON structure. But to build this structure I'm stuck with the following php procedure:
Code in PHP:
$query = "SELECT s1.question, s2.answers, s2.correct
FROM `questions` s1, `answers` s2
WHERE s1.id=s2.questionid AND s1.courseid=".$_POST['courseid']."";
$result = mysqli_query($mysqli, $query) or die ("<b>Select failed:</b> ".mysqli_error($mysqli));
$final_quiz = array();
$final_quiz['introduction'] = "Introduction text goes here";
while ($rows = mysqli_fetch_assoc($result_quiz)) {
$final_quiz['questions']['question'] = $rows['question'];
$final_quiz['questions']['question']['answers'] = array($rows['answers'], "correct"=> $rows['correct']);
}
// convert to JSON
$json = json_encode($final_quiz);
echo $json;
Expected JSON Output:
{
"introduction":"Some introductory text here",
"questions":[
{
"question":"Question number one here?",
"answers":["some incorrect answer", "a correct answer", "another incorrect answer"],
"correct":1}, // indicates an array key that is relates to keys in "answers"
...
]
}
How to organize multidimensional array in order to get above mentioned json structure? Any help would be appreciated.
UPDATES
The values in correct keys are indexes of the answers keys, i.e. if we have "correct":1 that would mean second value of answers key. Correct values for answers that come from MySQL are boolean (TRUE/FALSE). So, before putting all answers in answers_array_key as a set of answers one should remember newly assigned index array for the answer with TRUE value put that index array in correct_array_key as value. An example:
....
"answers":[0:"some incorrect answer", 1:"a correct answer", 2:"another incorrect answer"],
"correct":1}, // this is correct answer key
....
Hope that will that will explain the idea of desired json sturcture mentioned above.
I think this will produce the result you want.
while ($rows = mysqli_fetch_assoc($result_quiz)) {
$final_quiz['questions'][]= array(
'question' => $rows['question'],
'answers' => array($rows['answers']),
'correct'=> $rows['correct']
);
}
In your code, you are overwriting a single element of that array instead of appending the other questions
You can try to use the php json_encode command. (link on php.net -> http://php.net/manual/it/function.json-encode.php)
The link show some example of array structure. On php.net it says it works with each type of structure (not resources).
Edit: as i see you already use this command, but how is the actual output? How much is different from your desired one?
I believe this will solve it for you (I've used an array to test, I hope I got the question right).
You will need to change the foreach loop back to your while loop.
I might have used a bit of different naming, you might need to change a thing or 2 to match your exact names:
<?php
$tmp = array (
array("question"=> "this is a q", "answer"=>"incorrect", "correct" => false),
array("question"=> "this is a q", "answer"=>"incorrect1", "correct" => false),
array("question"=> "q1", "answer"=>"correct", "correct" => true),
array("question"=> "q1", "answer"=>"incorrect", "correct" => false),
array("question"=> "q1", "answer"=>"incorrect1", "correct" => false),
array("question"=> "this is a q", "answer"=>"incorrect1", "correct" => false),
array("question"=> "this is a q", "answer"=>"incorrect2", "correct" => false),
array("question"=> "this is a q", "answer"=>"correct", "correct" => true),
array("question"=> "this is a q", "answer"=>"incorrect3", "correct" => false)
);
$QAndA = array();
foreach ($tmp as $t){
if (!isset($QAndA[$t['question']]['answers']))
$QAndA[$t['question']]['answers'] = array();
$QAndA[$t['question']]['answers'][] = $t['answer'];
if ($t['correct'])
$QAndA[$t['question']]['correct'] = count($QAndA[$t['question']]['answers']) -1;
}
foreach ($QAndA as $q => $data){
$final_quiz['questions'][] = (object)array("question" => $q,
"answers" => $data['answers'],
"correct" => $data['correct']);
}
$json = json_encode($final_quiz);
echo $json;
?>
Result:
{
"questions": [{
"question": "this is a q",
"answers": ["incorrect", "incorrect1", "incorrect1", "incorrect2", "correct", "incorrect3"],
"correct": 4
}, {
"question": "q1",
"answers": ["correct", "incorrect", "incorrect1"],
"correct": 0
}]
}
I do want to apologize for the naming conventions here and the somewhat brute attitude this code presents, but it is very late here;
Add one counter $i and try the below code:
$i = 0;
while ($rows = mysqli_fetch_assoc($result_quiz)) {
$final_quiz['questions'][$i] = array(
'question' => $rows['question'],
//'answers' => $rows['answers'], UPDATE THIS LINE
'answers' => array(
'1' => $rows['answers'][1],
'2' => $rows['answers'][2],
'3' => $rows['answers'][3])
// Why I started from index one? if index is consecutive from 0 to n
// will remove the index in JSON, so start indexing from 1 and make some changes in ur code
'correct' => $rows['correct']
);
$i++;
}
this will work
Related
I'm trying to make a form with a bunch of questions which can be added to a radioBox, checkBox etc. I have made a .json file containing the questions and possible answers like this (this is just a small part of the file):
{
"questions": {
"0": {
"question":"How many products?",
"answers":["Less than 1000", "More than 1000", "More than 10000"],
"score":[1, 2, 3],
"info":"This is additional information for question 1"
}
,
"1":{
"question":"How many websites?",
"answers":["One", "Two", "Three"],
"score":[1, 2, 3],
"info":"This is additional information for question 2"
}
}
}
I use a class in which I have several functions to make array's which can be used on my regular .php page. I have made an array of questions using the following piece of code, which works:
$questions = [];
foreach($json['questions'] as $key => $value){
$this->questions[] = $value['question'];
}
Now I can just use question[0] to get the first question and question[1] for the second, which is really nice. What I am trying to do is create an array that contains all the answers per question so I can do something similar with the answers. Ideally, it would look something like this:
array:
arrayQuestion1Answers:
string: answer1
string: answer2
string: answer3
arrayQuestion2Answers:
string: answer1
string: answer2
string: answer3
That way I could do something like arrayQuestion1[0] to get the first answer from the first question, and arrayQuestion2[2] to get the third answer from the second question.
Thank you for reading my long (and possibly stupid) question, hope you can help!
Try this,
$json = '{
"questions": {
"0": {
"question":"How many products?","answers":["Less than 1000", "More than 1000", "More than 10000"],"score":[1, 2, 3],"info":"This is additional information for question 1"
}
,"1":{
"question":"How many websites?","answers":["One", "Two", "Three"],"score":[1, 2, 3],"info":"This is additional information for question 2"
}
}
}
';
$questions = json_decode($json,true);
$question = $questions['questions'];
foreach($question as $key => $que):
$answer['arrayQuestion'.$key.'Answers'] = $que['answers'];
endforeach;
echo '<pre>';
print_r($answer);
You say you already have functions to convert the JSOn to PHP arrays. Have you ever checked out json_decode()? It's a native PHP function to decode your JSON. It returns false on failure.
Furthermore: why are you indexing the objects in your questions object in your JSON? You might as well type:
{
"questions": [
{"somekey": "this_is_question_0"},
{"somekey": "this_is_question_1"}
]
}
That way they're automatically indexed.
To answer you actual question, if you use what I describe above, you can simply access a question's answers like this:
$questions = json_decode($json);
$answers_to_question_1 = $questions[0]['answers'] ?? []; // ?? [] means: if not set, make it an empty array. This is the null coalesce feature, available in PHP 7.0 and higher. See http://php.net/manual/en/migration70.new-features.php.
this question comes from the posting I found here:
DataTables Multiple Tables from Multiple JSON Arrays
I'd like to know the simplest and best way to generate the JSON below. I can see the pattern is 'JSON object -> Array Header -> Array -> JSON object' but I do not know how to do this in PHP, from a mySQLi query result. I imagine having a mySQL table with a 'policies' and 'services' column so the query might look something like:
Select name, id, score, type from myTable where type = 'policies' and
type = 'services'
And the result would come back something like:
name id score type
A 1 0 policies
B 2 0 services
But then how would I take that query and generate this JSON in php?
{
"Policies": [
{
"name": "A",
"id": "1",
"score": "0"
}
],
"Services": [
{
"name": "B",
"id": "2",
"score": "0"
}
]
}
Thanks for your help!
Start by creating the new empty array.
Then, iterate through the result and add it in the correct sub-array:
$new = [];
foreach ($result as $item) {
// Uppercase the first character
$type = ucfirst($item['type']);
if (!isset($new[$type])) {
// This type doesn't exist in the new array yet, let's create it.
$new[$type] = [];
}
// Add the item
$new[$type][] = $item;
}
// Output it as json
echo json_encode($new, JSON_PRETTY_PRINT);
The above code will also work if new types are added to the database.
PS. The JSON_PRETTY_PRINT argument is just to make the json string a bit more readable while developing. When everything looks good, you can remove it.
I'm creating this JSON thingy and I need to remove the last comma from it. (yes I know I could do a simple way instead of making the json myself, but I need it to be like this {"1":0,"2":4,"3":1.5}) So how can I do it? (And yes I have a working way in the code but it doesent display it like I need it.)
<?php
require 'dbConnect.script.php';
$query="SELECT * FROM `trash`";
if($is_query_run=mysql_query($query)){
print "{";
while($query_execute=$query_execute=mysql_fetch_assoc($is_query_run)){
echo '<tr><td>"'.$query_execute['id'].'"</td>:<td>'.$query_execute['weight'].',</td></tr>';
//$rows = array();
//$rows[] = $query_execute;
//print json_encode($rows);
}
print "}";
}
else{
echo "query notexecuted";
}
?>
In your example, you can simply create an array:
$array = ["1" => 0, "2" => 4, "3" => 1.5];
$json = json_encode($array);
Since this array doesn't start with a zero (which indexed arrays does), this would give you your desired result.
If you want to start with a zero, and still get an object back:
$array = ["0" => 2, "1" => 0, "2" => 4, "3" => 1.5];
you can use the option JSON_FORCE_OBJECT as a second parameter, like this:
$array = ["0" => 2, "1" => 0, "2" => 4, "3" => 1.5];
$json = json_encode($array, JSON_FORCE_OBJECT);
This will give you:
{
"0": 2,
"1": 0,
"2": 4,
"3": 1.5
}
Read more here: http://php.net/manual/en/function.json-encode.php
It's seldom a good idea to build your own encoders/decoders for things like this. It usually gets quite complicated pretty quick, and you will spend most of your time straighten out bugs and get stuck on edge cases. It's better to read up on the native functions. They have been tried and tested for years, and are often much better in regards of performance.
Whilst I concur json_encode is the nicest solution for producing JSON. To produce a nice comma separated output you could use the implode function.
Set-up your elements in an array, so for example:
$data = array('"1":0', '"2":4', '"3":1.5');
Then use implode like this
$output = implode(',', $data);
Which will give you an output of the data elements in the array as a comma separated list
if($is_query_run=mysql_query($query)){ //Here you execute the query
while($query_execute=$query_execute=mysql_fetch_assoc($is_query_run)){ //Here you get one row from execution result
$rows = array(); //You create array into $rows, what was in $rows before will be wiped
$rows[] = $query_execute; // You insert one row you just fetch from result to $rows
print json_encode($rows); // You encode $rows (which always has only one element as you wipe it every iteration)
}
}
So, create array before loop, and encode that array after loop, adding elements to array inside a loop is ok.
-Mr_KoKa #LinusTechTips.com
I get data from a .xlsx file, which I also put into an array(named $tableArray, I used PHPExcel for that). now i don't know how I can output even a single entry in my array.
I tried
$tableArray[1];
getting all the entries works with
var_dump($tableArray);
my code:
<?php
$excelReader = PHPExcel_IOFactory::createReaderForFile($fileName);
$excelReader->setReadDataOnly();
$excelObj = $excelReader->load($fileName);
$excelObj->getActiveSheet()->toArray();
$worksheetNames = $excelObj->getSheetNames($fileName);
$tableArray = array();
foreach($worksheetNames as $key => $sheetName){
$excelObj->setActiveSheetIndexByName($sheetName);
$tableArray[$sheetName] = $excelObj->getActiveSheet()->toArray();
}
var_dump($tableArray);
?>
Here's a few tips to help get you started.
If you want to see your array in a cleaner format on your browser, surround the var_dump() in a <pre> tag like so.
<?php
$myArray = [
"orange" => "foo",
"bar" => [
"test" => "more"
]
];
?>
<pre>
<?php var_dump($myArray); ?>
</pre>
This will help you understand your array structure better as it will be easier to read.
Accessing values in arrays is as easy as referencing the key. For example in the array above, if we want the value of orange, just echo $myArray["orange"];
If the value is another array, such as the key bar, and we want the value of test, we can just reference both keys in order echo $myArray["bar"]["test"];
You can use foreach() to loop through your array and perform action on each key => value pair.
<?php
$myArray = [
"orange" => "foo",
"bar" => [
"test" => "more"
]
];
foreach($myArray as $key => $value) {
var_dump($key);
var_dump($value);
}
If you're looking for more detailed information I'd recommend going through some of the courses on Code Academy. It will help you not only with this question, but others involving basic functionality of PHP.
Hope this helps!
I've an array titled $request as follows :
Array
(
[invite_emails] => suka#gmail.com, swat#gmail.com
[page_id] => 322
[ws_url] => http://app.knockknot.com/api/group/sendInvitation
)
After using json_encode($request) I got following output:
{
"invite_emails": "suka#gmail.com, swat#gmail.com",
"page_id": "322",
"ws_url": "http://app.knockknot.com/api/group/sendInvitation"
}
But actually I want the JSON object as follows :
{
"page_id": 322,
"invite_emails": [
"suka#gmail.com",
"swat#gmail.com"
],
"ws_url": "http://app.knockknot.com/api/group/sendInvitation"
}
How should I manipulate the array in PHP in order to get the above desired JSON object?
Please someone help me.
Split the list of emails using the comma:
$array["invite_emails"] = preg_split("#\s*,\s*#", $array["invite_emails"]);
I personally prefer using callback functions for readability and possibilities. To your purpose, array_walk should fit:
<?php
// reproducing array
$request = array(
"invite_emails" => "suka#gmail.com, swat#gmail.com",
"page_id" => 322,
"ws_url" => "http://app.knockknot.com/api/group/sendInvitation"
);
// callback finds a comma-separated string and explodes it...
array_walk($request, function (&$v,$k) {if ($k == 'invite_emails') $v = explode(", ", $v);});
// ... and then encode it to JSON
json_encode($request);
// testing
print_r($request);
OUTPUT:
{
"invite_emails":[
"suka#gmail.com",
"swat#gmail.com"
],
"page_id":322,
"ws_url":"http://app.knockknot.com/api/group/sendInvitation"
}
You are free to change the field if your needs changes, and even suppress it to be used with any field of the array.
Use PHP explode for example:
$array['invite_emails'] = explode(',',$array['invite_emails']);
To avoid spaces use preg_split (source):
$array['invite_emails'] = preg_split("/[\s,]+/", $array['invite_emails']);
This entry:
[invite_emails] => suka#gmail.com, swat#gmail.com
should be an array (currently, it is a string) in PHP, then in JSON it will look like you want it.