Forum Moderators: coopster

Message Too Old, No Replies

dynamic quiz

         

bysonary

6:54 pm on Feb 1, 2007 (gmt 0)

10+ Year Member



hello, I am in the process of planning to write a dynamic quiz like php application which will have questions stored in a database as well as answers etc.

I need this quiz to be administered though an online interface.

Here is the hard part, this quiz must have a feature where each answer to a question will result in the next question in the quiz relating to the answer before, for example

Q1: are you male or female?
A1: Male
A2: Female

A1 will lead to the following question

Q: did you ever play with action man as a child?

where as

A2 will lead to the following question

Q: did you ever play with barbie as a child

this is just an example set of questions but you get the idea right?

now I need the administrator to be able to specify the dependency of each question, i need the administrator to be able to say Q1 A1 will lead to Q5, Q1 A2 will lead to Q2, Q1 A3 will lead to Q3 and so on

can anyone tell me where I can begin with a project like this?

the plan i have is using the URL to pass the question number, e.g.

[mydomain.com...]

this will display question 5 and

[mydomain.com...]

will display question 1

sort of like this

Question 1 Start
If Answer = Answer 1 Then
goto question 5
elseif Answer = Answer 2 Then
goto question 6

and so on

I just need to know how i can get the goto part to work, it will need to somehow select the qnum from the db and put it in a variable which will be accessed throuhg a URL

maybe like this

$goto_question = 5;
header('Location: [mydomain.com...]

its all a bit of a mess in my head and i really need some guidance if anyone can offer any at all I would appreciate it.

mcibor

3:47 pm on Feb 2, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think what you are trying to do is not exactly a quiz but a survey.

What you can have is two tables:
questions: qid, question

answers: aid, qid, next_qid, answer

then the query for question is:
"SELECT question FROM questions WHERE qid='$qnum'"

and for answers:
"SELECT answer, next_qid FROM answers WHERE qid='$qnum'"

and in html you can put:
<select name="quiz">
<?php
while($answer = mysql_fetch_assoc...)
echo "<option value=\"{$answer['next_qid']}\">{$answer['answer']}</option>";
?>
</select>

Or you can input javascript and on submit submit to quiz.php?qnum and here put value from select.

Hope this helps
Michal

PS.
$goto_question = 5;
header('Location: [mydomain.com...]
will not work because of the single quotes - they don't parse the variables.
This will work:
header("Location: [mydomain.com...]

bysonary

7:50 am on Feb 3, 2007 (gmt 0)

10+ Year Member



Cheers mate, that really helps, I was using one table, I think two tables would b better now

Thanks again :-)

PS:

i dont quite understand

echo "<option value=\"{$answer['next_qid']}\">{$answer['answer']}</option>";

why use the next_qid here?

mcibor

2:32 pm on Feb 5, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Let me give you an example:

questions:
qid, question
1, "Which of these sports do you prefer?"
2, "Do you also like snowboarding?"
3, "Some other question..."

answers:
aid, qid, next_qid, answer
1, 1, 2, "Skiing"
2, 1, 3, "Swimming"
3, 2, 3, "Yes"
4, 2, 3, "No"
5, 3, ... some other answers.

So first question is "Which of these sports do you prefer?" with answers "Skiing" and "Swimming". However if you select skiing you will be served with additional question.
So the easiest way to ...

hmm I just spotted my mistake. :/ Sorry it has to be echo "<option value=\"{$answer['aid']}\">{$answer['answer']}</option>";
and better even hold the question id eg in hidden, or get
then on submit select
$sql = "SELECT * FROM answers WHERE aid='".(int)$_POST['quiz']."' AND qid='".(int)$_GET['qnum']."' LIMIT 1";

Hope this helps now.
With the idea I wanted to use before you couldn't get the answers ;)

Regards
Michal

bysonary

8:13 pm on Feb 6, 2007 (gmt 0)

10+ Year Member



on submit shouldnt it be more a case of selecting the next question rather than answers

$sql = "SELECT * FROM answers WHERE aid='".(int)$_POST['quiz']."' AND qid='".(int)$_GET['qnum']."' LIMIT 1";

you say on submit do that query, well how am i going to display the next question? surely on submit it should check the aid and find out what the next_qid is associated with that aid and then display that question from the questions db and also display any answers associated with that question?

you really are helping here and I would appreciate it if you could expand upon what i just said....

bysonary

9:32 pm on Feb 6, 2007 (gmt 0)

10+ Year Member



Hey mate I pretty much got this down so far and I think im on the home straight thanks to you.

here is the code i got.


<?php
include '/home/www/juttuffi/dbc.php';
$qid = $_GET['qid'];

$query1 = mysql_query("SELECT * FROM tquestions WHERE qid='$qid'");
if (mysql_numrows($query1) == 0)
{
echo "There is nothing in the database";
}
else
{
while ($qrow = mysql_fetch_array($query1,MYSQL_ASSOC))
{
echo $qrow['question']."<br>";

$query2 = mysql_query("SELECT * FROM tanswers WHERE qid='$qid' ORDER BY aid ASC");
if (mysql_numrows($query2) == 0)
{
echo "There is nothing in the database";
}
else
{
echo "<select name='quiz'>";
while ($arow = mysql_fetch_array($query2,MYSQL_ASSOC))
{
echo "<option value='".$arow['aid']."'>";
echo $arow['answer'];
echo "</option>";
}
echo "</select>";
}
}
}

Thanks for the help, this seems to display the answers and everything fine, just a case of working out all the if statements to direct to the next qid now but that shouldn't be tough.

Thanks again mate

mcibor

8:32 am on Feb 7, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Most important!
Filter your input.
There is a huge security leak in the code you wrote.
Imaging what would happen if someone entered your page with this link:

page.php?id=';TRUNCATE tquestions WHERE id>'0
Out go your questions.

However simple projection:
$qid = (int)$_GET['qid'];
will solve this problem.

Remember never to trust external data ($_GET, $_POST, $_REQUEST, $_COOKIE nor $_SERVER)

regards
Michal

bysonary

2:47 pm on Feb 7, 2007 (gmt 0)

10+ Year Member



thanks for that mate, you have taught me something there

bysonary

3:55 am on Feb 8, 2007 (gmt 0)

10+ Year Member



Hello, I have ran into a small problem with this set of scripts that I have tried to think about and cant seem to solve, the first page question.php is a kind of version of the code i posted above that leads to nextq.php which displays the next questions, here is the code for nextq.php the quoted area of code is the area i am stick with.

<?php
include '/home/www/juttuffi/dbc.php';
include '/home/www/juttuffi/header.php';
$aid = (int)$_POST['quiz'];

$query1 = mysql_query("SELECT * FROM tanswers WHERE aid='$aid'");
if (mysql_numrows($query1) == 0)
{
echo "There is nothing in the database";
}
else
{
while ($arow1 = mysql_fetch_array($query1,MYSQL_ASSOC))
{
$nextq = $arow1['next_qid'];
if ($nextq == 0)
{
$result = $result + $arow1['weight'];
echo "<br>END OF QUIZ";
echo $result;
}


else
{
$query2 = mysql_query("SELECT * FROM tquestions WHERE qid='$nextq'");
if (mysql_numrows($query2) == 0)
{
echo "There is nothing in the database";
}
else
{
echo "<table border='0' width='100%' cellspacing='0' cellpadding=2' class='tablemain'>";
echo "<tr>";
echo "<td width='100%' class='tableheader'>";
echo "<span class='tblheader'>";
echo "Quote Calculation Quiz";
echo "</span";
echo "</td>";
echo "</tr>";
echo "<tr>";
echo "<td width='100%' class='tablebody'>";
echo "<span class='tblbody'>";
while ($qrow = mysql_fetch_array($query2,MYSQL_ASSOC))
{
echo $qrow['question']."<br>";
$query3 = mysql_query("SELECT * FROM tanswers WHERE qid='$nextq' ORDER BY aid ASC");
if (mysql_numrows($query3) == 0)
{
echo "There is nothing in the database";
}
else
{
echo "<form name='quest' action='nextq.php' method='post'>";
echo "<select name='quiz'>";
while ($arow2 = mysql_fetch_array($query3,MYSQL_ASSOC))
{
echo "<option value='".$arow2['aid']."'>";
echo $arow2['answer'];
echo "</option>";
}
echo "</select>";
echo "<br><br><input type='submit' name='submit' value='Next Question'>";
echo "</form>";
}
echo "</span>";
echo "</td>";
echo "</tr>";
echo "</table>";
}
}
}
}
}
mysql_close($dbc);
?>

I added an extra field to answers table called weight, this gives each question a weighting and all the weightings to all the answers will be added together to give an overall weighting or result.

Now the way I have done this is that nextq.php submits to nextq.php therefore I cannot work out how to keep the weighting score from the previous instance of nextq.php

can anyone help me at all?

PS: I decided that if the next_qid was 0 that it would mean the end of the quiz/survey

mcibor

10:25 pm on Feb 8, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Remember it in $_SESSION['score']:

on each page:
<?php
if(!isset($_SESSION)) session_start();

and in getting the results:

$query1 = mysql_query("SELECT * FROM tanswers WHERE aid='$aid'");
if (mysql_numrows($query1) == 0)
{
echo "There is nothing in the database";
}
else
{
$arow1 = mysql_fetch_array($query1,MYSQL_ASSOC); // no need to loop - there is one result
{
$nextq = (int)$arow1['next_qid']; // doesn't hurt to use the projection here as well
if(!isset($_SESSION['score'])) $_SESSION['score'] = 0;
$_SESSION['score'] += $arow1['weight']; // I think you already use structure
// $a .= "text" which is $a = $a . "text", then $a += 2 is the same: $a = $a + 2;
if (!$nextq) // this is the same as $nextq == 0
{
echo "<br>END OF QUIZ";
echo $SESSION['score'];
}

else
{
$query2 = mysql_query("SELECT * FROM tquestions WHERE qid='$nextq'");
if (mysql_numrows($query2) == 0)
//here as well you can use if(!mysql_numrows($query2)), depends on you
{
echo "There is nothing in the database";
}
else
{ ...

Hope this helps!
Michal

More on session is to be read on
[php.net...]
and
[php.net...]

bysonary

6:14 pm on Feb 10, 2007 (gmt 0)

10+ Year Member



Is there anyway once the script has ended to sort of clear the $_SESSION['score'] variable

I notice clicking back in the browser adds to the score over and over, is there a way to clear the value once the end of the quiz has been reached and the real result has been echoed to the page or even stored in another variable and then clear the sessionv ariable?

mcibor

4:16 pm on Feb 13, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You would have to check for double posting the variable:
you can do it with such script:

if($_SESSION['rnd'] == $_POST['rnd']){
get the results from db, add score
$_SESSIOON['rnd'] = md5(rand());//or any other function that will give you a random string of letters and numbers

then in <form... select...
add
<input type="hidden" name="rnd" value="<?php echo $_SESSION['rnd'];?>">
...
</form>

This should work

To reset the score use
unset($_SESSION['score']);

regards
Michal

PS. Sorry for late answer

bysonary

9:44 pm on Feb 14, 2007 (gmt 0)

10+ Year Member



Cheers man, Ill apply that to the script, its almost finished now, I shouldn't be needing any more help with it, just want to say thanks again, been a real help :-).

bysonary

2:11 am on Feb 15, 2007 (gmt 0)

10+ Year Member



one last thing isnt vital but would be nice to know,i promise this is the last thing

i have the following code


echo '<table border="0" cellspacing="0" cellpadding="0">';
while ($arow = mysql_fetch_array($query1,MYSQL_ASSOC))
{
echo '<tr>';
echo '<td valign="top">';
$question = $arow['qid'];
$query2 = mysql_query("SELECT * FROM tquestions WHERE qid='$question'");
$qrow = mysql_fetch_array($query2,MYSQL_ASSOC);
echo "<b>(".$qrow['qid'].")</b></span>: ";
echo $qrow['question'];
echo '</td>';
echo '</tr>';
}
echo '</table>';

It echos about 20 lines of questions i want to make the first row light grey, the 2nd row white the 3rd row light grey the 4th row white the 5th row light grey and on and on,

can you please tell me if this is possible and how?

mcibor

11:02 am on Feb 15, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi, ask as many questions as you wish :D

I would do that with css:

echo '<table border="0" cellspacing="0" cellpadding="0">';
$i = 0;
while ($arow = mysql_fetch_array($query1,MYSQL_ASSOC))
{
//I haven't tested it, but should work:
$i = ($i + 1) % 2;//will return first 1, then 0, then 1, then 0, etc
echo "<tr class=\"table_row$i\">"; //use the " so that you parse variables
echo '<td valign="top">';
$question = $arow['qid'];
$query2 = mysql_query("SELECT * FROM tquestions WHERE qid='$question'");
$qrow = mysql_fetch_array($query2,MYSQL_ASSOC);
echo "<b>(".$qrow['qid'].")</b></span>: ";
echo $qrow['question'];
echo '</td>';
echo '</tr>';
}
echo '</table>';

and in your css use two styles:
table_row0
{
}

and
table_row1
{
}

PS. I'm interested, if
$i++ %= 2;
would work :) It looks quite strange I must say! - it doesn't, but
$i2 = ++$i2 % 2;
does work :D

Take care
Michal

bysonary

1:48 pm on Feb 15, 2007 (gmt 0)

10+ Year Member



Hey I tested both your examples the only one which works is the

$i = ($i + 1) % 2;

the other one

$i++ %= 2;

doesn't, gets an unexpected T_MOD_EQUAL so i guess it doesn't want to work that way

Thanks again mate :-)

bysonary

2:10 pm on Feb 15, 2007 (gmt 0)

10+ Year Member



Slight problem with the results of the colouring of the table rows, I have made some changes so it can suit my needs perfectly but there is one big problem,, it would be best if you could first see the code, it is quite long and this is just a snippet of it.


echo '<span class="tblbody">';
while ($arow = mysql_fetch_array($query1,MYSQL_ASSOC))
{
$i = ($i + 1) % 2;
echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\" class=\"table_row$i\">";
echo "<tr>";
echo '<td valign="top" width="100%">';
$question = $arow['qid'];
$query2 = mysql_query("SELECT * FROM tquestions WHERE qid='$question'");
$qrow = mysql_fetch_array($query2,MYSQL_ASSOC);
echo "<b>(".$qrow['qid'].")</b></span>: ";
echo $qrow['question'];
echo '</td>';
echo '</tr>';
}
echo '</table>';
echo '</span>';
echo '</td>';
echo '<td width="25%" class="tablebody">';
echo '<span class="tblbody">';
while ($arow1 = mysql_fetch_array($query3,MYSQL_ASSOC))
{
$i = ($i + 1) % 2;
echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\" class=\"table_row$i\">";
echo "<tr>";
echo '<td valign="top" width="100%">';
echo $arow1['answer'];
echo '</td>';
echo '</tr>';
}
echo '</table>';
echo '</span>';
echo '</td>';

As you can no doubt see I have two columns one containing the Question and one containing the answer, in the actual script I have about 5 columns but this should be enough to explain my problem.

I moved the <class=\"table_row$i\"> into the table tag so it would colour the entire table, I wanted the entire top row that includes where the Question is echoed and where the answer is echoed to be the same colour, however

the first line where the question is displayed is grey, the second line is white and so on, the problem is that the first line iof the answers is white and i want it to be the same colour as the first line of the questions if you understand me, the pattern is kind of like a chess board pattern, I would give you a linkt o see but i dont think links to personal websites are allowed on this forum.

Is there a way around this chess board like pattern, and if so could you help me out with it?

bysonary

2:17 pm on Feb 15, 2007 (gmt 0)

10+ Year Member



fixed it mate no need to reply, I just changed each instance of $i to Ģi1, $i2 and so on

Thanks for the help it works a charm :-)

EDIT: Ģi1? whats that all about an english version of php :-¦ should be $i1

mcibor

10:28 am on Feb 16, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



To say the truth there was a workaround your problem: reseting the $i :)

...echo '<span class="tblbody">';
$i = 0;
while ($arow1 = mysql_fetch_array($query3,MYSQL_ASSOC))
{
$i = ($i + 1) % 2;
echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\" class=\"table_row$i\">";
echo "<tr>";
echo '<td valign="top" width="100%">';
echo $arow1['answer'];
echo '</td>';
echo '</tr>'; ...

would work fine :D

PS. No, you can't post urls here, but there is always a sticky mail.

Take care
Michal