/    Sign up×
Community /Pin to ProfileBookmark

How to make a simple PHP with SQL quiz

Morning people hope you’re all well. I really need some advice from yourselfs. As you might know I’m in the middle of creating my own website. The site will let users register and to log in.

I want to create a quiz I have found some code from this site [URL=”http://www.gotcode.org/blog.php?id=290″]http://www.gotcode.org/blog.php?id=290[/URL]. I want to create a multiple choice quiz where there are 20 random questions from a bank of 100 questions in the database where users can take the quiz and test their knowledge. The quiz has got to be multiple choice and have a selection of 3 wrong answers and 1 correct answer with radio buttons and a button where the users can press “next” to the next question.

At the end of the quiz the users will then be able to see how well they have done with a percentage out of 100 to see how well they have done. With the questions and answers they have selected. I then want the answers to be put into the database and to show on the users personal profile where they can track their progress. It will be a list of each quiz they have taken with the time and date. Along with the amount of questions they have taken, along with they can click on each quiz (dated and timed) and they can see how well they have done and track their progress.

I know how i want it to look its now just getting it started. The above link I did get the quiz sorted and I did get it to work but some of the code now is out of date.

I’m asking you guys if you can give me any suggestions as to where or how I can start this. This website it a re-creation what I did when I was at university for my dissertation/ final year project to help people like myself who suffer from dyscalculia and its a learning aid to help them. The site now is a portfolio to show my skills and knowledge to help me to get my first graduate PHP web developer job. I would really appreciate any help you guys could give me.

Thanks in advance

Rich

to post a comment
PHP

12 Comments(s)

Copy linkTweet thisAlerts:
@NogDogMar 16.2015 — I tend to be data model centric, so once I know what I want to do, I start thinking about what database tables are needed. For the quiz itself, I see at least 2 tables: questions and answers. Each question would have the question text along with any other info you need for it. Each answer would, in addition to the answer text, include a question_id to point to which question it applies to, and a boolean field to indicate if it is the correct answer or not. Then when you pull your random questions from the question table, you'd also then pull the related questions, probably via an INNER JOIN.
Copy linkTweet thisAlerts:
@stokie-ruchauthorMar 16.2015 — I tend to be data model centric, so once I know what I want to do, I start thinking about what database tables are needed. For the quiz itself, I see at least 2 tables: questions and answers. Each question would have the question text along with any other info you need for it. Each answer would, in addition to the answer text, include a question_id to point to which question it applies to, and a boolean field to indicate if it is the correct answer or not. Then when you pull your random questions from the question table, you'd also then pull the related questions, probably via an INNER JOIN.[/QUOTE]

I have managed to find the code from the quiz that I created a few months ago (from the website that I mentioned in the first post)

below is the code

[code=php]<?php
//Connect with mysql
$db = new mysqli("127.0.0.1", "root", "", "quiz");

//Perform the query to choose random questions
$query = $db->query("SELECT * FROM table ORDER BY RAND() LIMIT 20");

while ($row = $query->fetch_assoc()):
$question = $row['question'];
echo $question . "<br />";
endwhile;

//close result
$query->close();
//Close connection
$db->close();

session_start();
if (isset($_GET['question'])) {
$question = preg_replace('/[^0-9]/', "", $_GET['question']);
$next = $question + 1;
$prev = $question - 1;
} // <--- I added this brace. You need to double-check it logically belongs here
if (!isset($_SESSION['qid_array']) && $question != 1) {
$msg = "Sorry! No cheating.";
header("location: start.php?msg=$msg");
exit();
}
if (isset($_SESSION['qid_array']) && in_array($question, $_SESSION['qid_array'])) {
$msg = "Sorry, Cheating is not allowed. You will now have to start over. Haha.";
unset($_SESSION['answer_array']);
unset($_SESSION['qid_array']);
session_destroy();
header("location: start.php?msg=$msg");
exit();
}
if (isset($_SESSION['lastQuestion']) && $_SESSION['lastQuestion'] != $prev) {
$msg = "Sorry, Cheating is not allowed. You will now have to start over. Haha.";
unset($_SESSION['answer_array']);
unset($_SESSION['qid_array']);
session_destroy();
header("location: start.php?msg=$msg");
exit();
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Quiz Page</title>

<script type="text/javascript">
function countDown(secs,elem) {
var element = document.getElementById(elem);
element.innerHTML = "You have "+secs+" seconds remaining.";
if(secs < 1) {
var xhr = new XMLHttpRequest();
var url = "userAnswers.php";
var vars = "radio=0"+"&qid="+<?php echo $question; ?>;
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
alert("You did not answer the question in the allotted time. It will be marked as incorrect.");
clearTimeout(timer);
}
}
xhr.send(vars);
document.getElementById('counter_status').innerHTML = "";
document.getElementById('btnSpan').innerHTML = '<h2>Times Up!</h2>';
document.getElementById('btnSpan').innerHTML += '<a href="quiz.php?question=<?php echo $next; ?>">Click here now</a>';
}
secs--;
var timer = setTimeout('countDown('+secs+',"'+elem+'")',1000);
}

function getQuestion(){
var hr = new XMLHttpRequest();
hr.onreadystatechange = function(){
if (hr.readyState==4 && hr.status==200){
var response = hr.responseText.split("|");
if(response[0] == "finished"){
document.getElementById('status').innerHTML = response[1];
}
var nums = hr.responseText.split(",");
document.getElementById('question').innerHTML = nums[0];
document.getElementById('answers').innerHTML = nums[1];
document.getElementById('answers').innerHTML += nums[2];
}
}
hr.open("GET", "questions.php?question=" + <?php echo $question; ?>, true);
hr.send();
}
function x() {
var rads = document.getElementsByName("rads");
for ( var i = 0; i < rads.length; i++ ) {
if ( rads[i].checked ){
var val = rads[i].value;
return val;
}
}
}
function post_answer(){
var p = new XMLHttpRequest();
var id = document.getElementById('qid').value;
var url = "userAnswers.php";
var vars = "qid="+id+"&radio="+x();
p.open("POST", url, true);
p.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
p.onreadystatechange = function() {
if(p.readyState == 4 && p.status == 200) {
document.getElementById("status").innerHTML = '';
alert("Thanks, Your answer was submitted"+ p.responseText);
var url = 'quiz.php?question=<?php echo $next;

?>';

window.location = url;
}
}
p.send(vars);
document.getElementById("status").innerHTML = "processing...";
}
window.oncontextmenu = function(){
return false;
}
</script>


</head>

<body onLoad="getQuestion()">
<div id="status">
<div id="counter_status"></div>
<div id="question"></div>
<div id="answers"></div>
</div>


</script>
</body>
</html> [/code]


When I try and run the page on my local host I'm getting the following error message:


Fatal error: Call to a member function fetch_assoc() on a non-object in C:xampphtdocsquiz.php on line 8
Copy linkTweet thisAlerts:
@rootMar 16.2015 — what about $row=$result->fetch_array()
Copy linkTweet thisAlerts:
@NogDogMar 16.2015 — The "on a non-object" part of the error message usually means that your query failed to run on the DB server for some reason, so instead of getting a result object of some sort, you got a Boolean false, instead. So where you do the $db->query() before that, you need to check if the return value is false, and if so, do some debugging on it.
Copy linkTweet thisAlerts:
@stokie-ruchauthorMar 17.2015 — The "on a non-object" part of the error message usually means that your query failed to run on the DB server for some reason, so instead of getting a result object of some sort, you got a Boolean false, instead. So where you do the $db->query() before that, you need to check if the return value is false, and if so, do some debugging on it.[/QUOTE]

hey ahh right ok thanks for that..... sorry to sound like an idiot but how on earth do I add error checking then to it?
Copy linkTweet thisAlerts:
@NogDogMar 17.2015 — This is just some temporary debug code, but you don't want to die() and spew DB info in the real thing.
[code=php]
$query = $db->query("SELECT * FROM table ORDER BY RAND() LIMIT 20");
if($query == false) {
die("output debug info here");
}
[/code]

Since I don't know off-hand what DB extension you're using, I can't tell you what to use inside of the die() expression, but you want whatever the applicable function or property is that outputs the last DB error message.
Copy linkTweet thisAlerts:
@stokie-ruchauthorMar 20.2015 — This is just some temporary debug code, but you don't want to die() and spew DB info in the real thing.
[code=php]
$query = $db->query("SELECT * FROM table ORDER BY RAND() LIMIT 20");
if($query == false) {
die("output debug info here");
}
[/code]

Since I don't know off-hand what DB extension you're using, I can't tell you what to use inside of the die() expression, but you want whatever the applicable function or property is that outputs the last DB error message.[/QUOTE]


Hey thanks for that and sorry for the late replay. When I run the page its now displaying

output debug info here

Sorry to sound like a tit! But how do I put debug info there?
Copy linkTweet thisAlerts:
@stokie-ruchauthorMar 20.2015 — I have put some code into the quiz code this is how it looks at the moment:

[code=php]<?php
//Connect with mysql
$db = new mysqli("127.0.0.1", "root", "", "quiz");

//Perform the query to choose random questions
$query = $db->query("SELECT * FROM table ORDER BY RAND() LIMIT 20");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %sn", mysqli_connect_error());
exit();
}

if (!mysqli_query($link, "SET a=1")) {
printf("Errormessage: %sn", mysqli_error($link));
}

/* close connection */
mysqli_close($link);
while ($row = $query->fetch_assoc()):
$question = $row['question'];

echo $question . "<br />";
endwhile;

//close result
$query->close();
//Close connection
$db->close();

session_start();
if (isset($_GET['question'])) {
$question = preg_replace('/[^0-9]/', "", $_GET['question']);
$next = $question + 1;
$prev = $question - 1;
} // <--- I added this brace. You need to double-check it logically belongs here
if (!isset($_SESSION['qid_array']) && $question != 1) {
$msg = "Sorry! No cheating.";
header("location: start.php?msg=$msg");
exit();
}
if (isset($_SESSION['qid_array']) && in_array($question, $_SESSION['qid_array'])) {
$msg = "Sorry, Cheating is not allowed. You will now have to start over. Haha.";
unset($_SESSION['answer_array']);
unset($_SESSION['qid_array']);
session_destroy();
header("location: start.php?msg=$msg");
exit();
}
if (isset($_SESSION['lastQuestion']) && $_SESSION['lastQuestion'] != $prev) {
$msg = "Sorry, Cheating is not allowed. You will now have to start over. Haha.";
unset($_SESSION['answer_array']);
unset($_SESSION['qid_array']);
session_destroy();
header("location: start.php?msg=$msg");
exit();
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Quiz Page</title>

<script type="text/javascript">
function countDown(secs,elem) {
var element = document.getElementById(elem);
element.innerHTML = "You have "+secs+" seconds remaining.";
if(secs < 1) {
var xhr = new XMLHttpRequest();
var url = "userAnswers.php";
var vars = "radio=0"+"&qid="+<?php echo $question; ?>;
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
alert("You did not answer the question in the allotted time. It will be marked as incorrect.");
clearTimeout(timer);
}
}
xhr.send(vars);
document.getElementById('counter_status').innerHTML = "";
document.getElementById('btnSpan').innerHTML = '<h2>Times Up!</h2>';
document.getElementById('btnSpan').innerHTML += '<a href="quiz.php?question=<?php echo $next; ?>">Click here now</a>';
}
secs--;
var timer = setTimeout('countDown('+secs+',"'+elem+'")',1000);
}

function getQuestion(){
var hr = new XMLHttpRequest();
hr.onreadystatechange = function(){
if (hr.readyState==4 && hr.status==200){
var response = hr.responseText.split("|");
if(response[0] == "finished"){
document.getElementById('status').innerHTML = response[1];
}
var nums = hr.responseText.split(",");
document.getElementById('question').innerHTML = nums[0];
document.getElementById('answers').innerHTML = nums[1];
document.getElementById('answers').innerHTML += nums[2];
}
}
hr.open("GET", "questions.php?question=" + <?php echo $question; ?>, true);
hr.send();
}
function x() {
var rads = document.getElementsByName("rads");
for ( var i = 0; i < rads.length; i++ ) {
if ( rads[i].checked ){
var val = rads[i].value;
return val;
}
}
}
function post_answer(){
var p = new XMLHttpRequest();
var id = document.getElementById('qid').value;
var url = "userAnswers.php";
var vars = "qid="+id+"&radio="+x();
p.open("POST", url, true);
p.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
p.onreadystatechange = function() {
if(p.readyState == 4 && p.status == 200) {
document.getElementById("status").innerHTML = '';
alert("Thanks, Your answer was submitted"+ p.responseText);
var url = 'quiz.php?question=<?php echo $next;

?>';

window.location = url;
}
}
p.send(vars);
document.getElementById("status").innerHTML = "processing...";
}
window.oncontextmenu = function(){
return false;
}
</script>


</head>

<body onLoad="getQuestion()">
<div id="status">
<div id="counter_status"></div>
<div id="question"></div>
<div id="answers"></div>
</div>


</script>
</body>
</html> [/code]


I'm now getting the following


Notice: Undefined variable: link in C:xampphtdocsquiz.php on line 13

Warning: mysqli_query() expects parameter 1 to be mysqli, null given in C:xampphtdocsquiz.php on line 13

Notice: Undefined variable: link in C:xampphtdocsquiz.php on line 14

Warning: mysqli_error() expects parameter 1 to be mysqli, null given in C:xampphtdocsquiz.php on line 14

Errormessage:

Notice: Undefined variable: link in C:xampphtdocsquiz.php on line 18

Warning: mysqli_close() expects parameter 1 to be mysqli, null given in C:xampphtdocsquiz.php on line 18

Fatal error: Call to a member function fetch_assoc() on a non-object in C:xampphtdocsquiz.php on line 19
Copy linkTweet thisAlerts:
@rootMar 20.2015 — You are mixing OO methods and Procedural methods, which I beleive is part of the problem here, you don't seem to be grasping the fact that you make a mysqli connection via an OO method in to $db but you refer to $link in the script, this is the sort of thing that reading the error is important, you can save a lot of time and speed up your progress by watching for typos.

if ([B]mysqli_connect_errno()[/B]) { [COLOR="#B22222"][B] ---&gt;[/B][/COLOR][B] $db-&gt;connect_errno[/B]
printf("Connect failed: %sn", [B]mysqli_connect_error()[/B]); [COLOR="#B22222"][B] ---&gt;[/B][/COLOR][B] $db-&gt;connect_errno[/B]
exit();
}

if (!mysqli_query($link, "SET a=1")) { ---&gt; $db-&gt;query("SET a=1")
printf("Errormessage: %sn", [B]mysqli_error($link)[/B]); [COLOR="#B22222"][B] ---&gt;[/B][/COLOR] [B] $db-&gt;error()[/B]
}

/* close connection */
[B]mysqli_close($link[/B]); [COLOR="#B22222"][B] ---&gt;[/B][/COLOR] [B]$db-&gt;close();[/B]


I shall leave you to work out the final bits.
Copy linkTweet thisAlerts:
@rootMar 20.2015 — After a bit of mooching about the interwebs, it would appear that you're cutting and pasting blocks of code as I have been looking at your code and its been a case of where have I seen that before... seen some on PHP.net, W3Schools and elsewhere and expecting them to work... Sorry to say that life is not as simple as that ?

By all means cut and past code BUT understand what it is that you're cutting and pasting together. You need to remember to watch for variables, names and possible clashes and keeping it all in one genre, chose either OO or procedural.

OO type

$object->property

$object->method();

Procedural

$variable = sime_function_class( $parameters);


and this is something that was impressed on me, [B]session_start()[/B] NEEDS to be on the first line after the <?php tag, its all to do with browser sending headers with the page, start too late and $_SESSION will be null.
Copy linkTweet thisAlerts:
@stokie-ruchauthorMar 20.2015 — You are mixing OO methods and Procedural methods, which I beleive is part of the problem here, you don't seem to be grasping the fact that you make a mysqli connection via an OO method in to $db but you refer to $link in the script, this is the sort of thing that reading the error is important, you can save a lot of time and speed up your progress by watching for typos.

if ([B]mysqli_connect_errno()[/B]) { [COLOR="#B22222"][B] ---&gt;[/B][/COLOR][B] $db-&gt;connect_errno[/B]
printf("Connect failed: %sn", [B]mysqli_connect_error()[/B]); [COLOR="#B22222"][B] ---&gt;[/B][/COLOR][B] $db-&gt;connect_errno[/B]
exit();
}

if (!mysqli_query($link, "SET a=1")) { ---&gt; $db-&gt;query("SET a=1")
printf("Errormessage: %sn", [B]mysqli_error($link)[/B]); [COLOR="#B22222"][B] ---&gt;[/B][/COLOR] [B] $db-&gt;error()[/B]
}

/* close connection */
[B]mysqli_close($link[/B]); [COLOR="#B22222"][B] ---&gt;[/B][/COLOR] [B]$db-&gt;close();[/B]


I shall leave you to work out the final bits.[/QUOTE]


right ok thanks for that I will have a look
Copy linkTweet thisAlerts:
@briantarrJul 16.2015 — Quick question: have you ever considered doing this with a quiz authoring tool and/or possibly even a Learning Management System? There are many free/open source options out there. If you’re interested, I could advise you…

Though, it does look like you’re determined to do this yourself with PHP and SQL. In which case, I salute you and wish you luck!
×

Success!

Help @stokie-ruch spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.27,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...