Make Your Own PHP Quiz (part 5)

You can download the entire source code for this series here PHP Quiz (11.21 KB)

At the end of the last post, we had an index page allowing users to register for the quiz (or not) via 2 forms. Now we need to display the questions/answers on ‘test.php’.
Inside the #quiz div, replace the content of the heading and paragraph with the following.

<h2>Acronym <?php echo $num+1; ?>:</h2>
<p>What does <strong><?php echo $questions[$num]; ?></strong> stand for?</p>

$num is our counter variable. At the start of the quiz, we set it to 0. We did this because the first key in an array is 0. Therefore, ‘echo $questions[$num];’ prints out the first question from the $questions array. Inside the h2, we have to add 1 to the value of $num as ‘Acronym 0′ wouldn’t make much sense!
Next, in the form, you’ll see that there is an empty pair of <ul> tags. Insert the following inside them.

First, we shuffle the corresponding array of answers

<ul>
<?php
shuffle_assoc($answers[$num]);
?>
</ul>

Then we loop through the answers…

<ul>
<?php
shuffle_assoc($answers[$num]);
foreach ($answers[$num] as $answer) {
?>
</ul>

…and echo a list item containing a radio box and label for each answer.

<ul>
<?php
shuffle_assoc($answers[$num]);
foreach ($answers[$num] as $answer) {
    echo "<li><input type=\"radio\" id=\"$answer\" value=\"$answer\" name=\"answers\" />\n";
    echo "<label for=\"$answer\">$answer</label></li>\n";
}
?>
</ul>

While this works fine, there is a problem. If, like in my example, your answers are sentences rather than one word, the above code won’t validate. That’s because an element’s id can’t contain spaces. To get around this, we’ll use str_replace() to change the spaces into underscores.

<ul>
<?php
$pattern = ' ';
$replace = '_';
shuffle_assoc($answers[$num]);
foreach ($answers[$num] as $answer) {
    $answer2 = str_replace($pattern,$replace,$answer);
    echo "<li><input type=\"radio\" id=\"$answer2\" value=\"$answer2\" name=\"answers\" />\n";
    echo "<label for=\"$answer2\">$answer</label></li>\n";
}
?>
</ul>

One last thing to add to the form is the value for the hidden field ‘num’. Unsurprisingly, that looks like this:

<p><input type="hidden" name="num" value="<?php echo $num; ?>" />

So now we have the question/answers displayed on the page, we need to process the submitted answer on each form submission. The question/answer form has a hidden field with the name of ’submitter’. By checking for that, we can tell if the user has answered a question. At the top of ‘test.php’ just after the ‘require_once’ lines and before the check to see if the user wanted to register we put this line:

require_once('functions.php');
require_once('questionsandanswers.php');
if (!isset($_POST['submitter'])) {
    if(isset($_POST['register'])) { ......

Notice the exclamation mark before ‘isset’. This is the negation operator. It turns the if statement on its head. With the negation operator, the if statement is checking to see whether $_POST['submitter'] is not set. This line is therefore saying: if $_POST['submitter'] isn’t set (a question hasn’t been answered), continue checking to see if the user wants to register.

If a question has been answered, we need the code to process it. We start by typecasting $_POST['num'] to an integer and assigning it to the variable $num

if (!isset($_POST['submitter'])) {
    if(isset($_POST['register'])) { ..//register check code goes here}
} else {
$num = (int) $_POST['num'];

Then we use str_replace() again to replace the underscores with spaces.

if (!isset($_POST['submitter'])) {
    if(isset($_POST['register'])) { ..//register check code goes here}
} else {
$num = (int) $_POST['num'];
$postedanswer = str_replace("_"," ",$_POST['answers']);

Next, we need to check if the submitted answer was the correct one and act accordingly: If the answer was correct (it matches the first answer in the related array), we add it to the $_SESSION['correct'] array and increase the score by 1. If not, it goes in to the $_SESSION['wrong'] array.

if (!isset($_POST['submitter'])) {
    if(isset($_POST['register'])) { ..//register check code goes here}
} else {
$num = (int) $_POST['num'];
$postedanswer = str_replace("_"," ",$_POST['answers']);
if ($postedanswer == $answers[$num]['0']) {
    $_SESSION['score']++;
    $_SESSION['correct'][] = $postedanswer;
} else {
    $_SESSION['wrong'][] = $postedanswer;
}

Finally, we check the value of $num. If it is less than the number of questions, we’ll increase it by one (which means that when the page is displayed, the next set of question/answers are shown). If $num is equal to the number of questions, that means all questions have been answered. In that case, we’ll create a new variable called $last and set it to ‘true’ and we’ll also create a new session variable called ‘finished’ and set it to ‘yes’.

if (!isset($_POST['submitter'])) {
    if(isset($_POST['register'])) { ..//register check code goes here}
} else {
$num = (int) $_POST['num'];
$postedanswer = str_replace("_"," ",$_POST['answers']);
if ($postedanswer == $answers[$num]['0']) {
    $_SESSION['score']++;
    $_SESSION['correct'][] = $postedanswer;
} else {
    $_SESSION['wrong'][] = $postedanswer;
}
if ($num &lt; count($questions)-1) {
    $num++;
} else {
    $last = true;
    $_SESSION['finished'] = 'yes';
}

The $last variable acts like a flag. If it doesn’t exist (there are still questions to answer), we continue to display the form. If it does exist, we show the user their final score. Just inside the #quiz div, put the following…

<?php if (!$last) { //display the form  
?>

… and then after the closing </form> tag, place the following:

<?php } else { 
echo "<h2 id=\"score\">{$_SESSION['user']}, your final score is:</h2>\n
<h3>{$_SESSION['score']}/20</h3><h4>Verdict:</h4>";
if($_SESSION['score'] <= 5) echo "<p id=\"verdict\">Witty Remark #1</p>\n";
if(($_SESSION['score'] > 5) && ($_SESSION['score'] <= 10)) echo "<p id=\"verdict\">Witty Remark #2</p>\n";
if(($_SESSION['score'] > 10) && ($_SESSION['score'] <= 15)) echo "<p id=\"verdict\">Witty Remark #3</p>\n";
if($_SESSION['score'] > 15) echo "<p id=\"verdict\">Witty Remark #4</p>";
echo "<p id=\"compare\"><a href=\"results.php\">See how you compare!</a></p>";
}?>

The code above checks the $_SESSION['score'] variable and outputs whatever you want depending on that score.

And that’s the end of part 5. All that remains of this mini-series is storing usernames and scores in an xml file and displaying that on the page. If you’ve followed along so far, the next part will be a doddle :)

Part 1
  • Part 2
  • Part 3
  • Part 4
  • Part 6
  • Final Part
  • Feed IconFollow me on Twitter





    Make ElanMan happy and be the first to comment.

    Leave a Comment







    XHTML: You can use the following tags in your comments: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">