Build an interactive quiz with PHP + JS

By just using PHP, MySQL, JS, AJAX, and a little bit of fun, you can create a Buzzfeed-like quiz without the use of a 3rd party application.

Heidi Olsen
8 min readNov 18, 2015



If you are anything like me, you’ve wasted numerous hours of ‘work time’ taking online quizzes to see Which Character From “The NeverEnding Story” Are You?(spoiler alert, I got Teeny Weeny). After creating a highly successful Pin to Win Holiday Campaign for our partner Fred Meyer Jewelers last year, we were challenged to make an even more engaging holiday campaign this year. We dreamed up our very own interactive gift guide where we asked their customers a series of questions to find the perfect gift for their loved one.

The campaign is a huge success and was a lot of fun to develop. In my preliminary research, I saw very little resources on how to create a quiz of this magnitude without using a 3rd party application, so I wanted to share. After all, it is almost time for yearly reviews and I have some wasted time to make up for.


  • Paper/Pen
  • Spreadsheet Program (I recommend Google Docs)
  • Text Editor
  • phpMyAdmin


  • Intermediate PHP/MySQL
  • Intermediate JS/AJAX
  • Grab a fresh cup of coffee and let’s get started!


Your first task is to set up the logic that will determine the outcome of your quiz. For this demo, I created a quiz to determine “Which eROI Crew Member Are You?”. There are 31 staff members at eROI, including myself, that I would then need to divide into distinct categories. These categories could include Athletic, Family-Oriented, Entertaining, etc. I discovered a Venn Diagram with 5 intersecting circles that result in 31 unique category combinations, perfect for the number of eROI employees. I settled on five categories and assigned each person to a category combination. Experiment with making a Venn Diagram to fit the needs of your quiz.


Your next task is to build a simple form that will collect the answers from the user. I recommend using a responsive framework such as Foundation to save you time and energy. Foundation is built on a flexible grid system and has built-in form styling and validation. Starting with an established, stable framework allows you to focus on the quiz instead of building the foundation. After you download the framework, save your index.html as index.php. Set your <input> type to “radio” so only one answer can be submitted for each question. Each radio button input is a question will have the same Name (i.e. Q1, Q2) and a unique Value (i.e. Q1A1 through Q10A5. The form will have a method of “post”, an id of “quiz” and a form action of “quiz.php” which is a file we will be creating later on.

form method=”post” id=”quiz” action=”quiz.php”> <input type=”radio” value=”Q1A1" name=”Q1" <?php if (isset($Q1) && $Q1==”Q1A1") echo “checked”;?>>

Create a <div> after your <form> that will display your result. Next create an additional <div> with an error message. Give the <div class= “hide” that is set to display: none; in your CSS.

<div id=”result”></div> <div id=”error” class=”hide”>There was an error in your submission.</div>


Now that we have the logic and form squared away, it is time to build the database! While this quiz could be completed with just one table, two tables made more sense in case I wanted to reuse this logic for future quizzes. Create a new spreadsheet and add two tabs. The first tab will be your quiz key and the second will be your quiz map.

In this tab you will be creating a table to help map your questions to your categories. You will need three columns: id, question, category. id: You need a row for each question in your quiz multiplied by the number of possible answers. For example, if your quiz is ten questions long with five answers for each question, you will have 50 results (or rows) to map. Label this column 1–50. question:

Match this column to the radio button values in your form. The values here will designate the answer, in the end. In this example we use Q1A1-Q10A5, where Q1A1 stands for the first category and the value to return. category: This is the column where you will add the categories A-E. Assign a single category to each answer in a question and mix up the order to appear random. For instance, you do not want the first answer of each question to be category A. QUIZ MAP In this tab you will be creating a table to help map your categories to your result. You will need to create at least three columns: id, result, result_category.

id: Label this column 1–31 or the number of results you have. result: This is where you list the results for your quiz. You can create additional columns for each result to include an image and description with your results. result_category: This is the category combination for each result. Multiple results cannot have the same result_category so double-check that each category combination is unique to that result. Once you have completed the spreadsheets, export or download each table as a CSV. Login to your site’s phpMyAdmin, create a database called db_quiz with two tables: quiz_key and quiz_map. Import your respective CSVs into those tables.


Create a new file in your project directory called ‘quiz.php’. This is going to contain all of the code responsible for querying the database. First you will be connecting to your database:

$connect=mysql_connect(“localhost”,”root”,”root”) or die(“Unable to Connect”); mysql_select_db(“db_quiz”) or die(“Could not open the db”);

Then create question variables and assign them to the values submitted through the form submission:

$Q1 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q1’])))); 
$Q2 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q2’]))));
$Q3 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q3’]))));
$Q4 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q4’]))));
$Q5 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q5’]))));
$Q6 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q6’]))));
$Q7 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q7’]))));
$Q8 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q8’]))));
$Q9 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q9’]))));
$Q10 = htmlspecialchars(trim(stripslashes(strip_tags($_POST[‘Q10’]))));

Next query the quiz key table to find the result of each question:

$query = “SELECT category FROM quiz_key WHERE question IN (‘$Q1’,’$Q2',’$Q3',’$Q4',’$Q5',’$Q6',’$Q7',’$Q8',’$Q9',’$Q10')”; $result = mysql_query($query);

Then you will set your category variables to 0 before you loop through the result and add up each category:

$cat_a = $cat_b = $cat_c = $cat_d = $cat_e = 0; while($row = mysql_fetch_array($result)) { $cat = $row[‘category’]; if ($cat == “A”) { $cat_a += 1; } elseif ($cat == “B”) { $cat_b += 1; } elseif ($cat == “C”) { $cat_c += 1; } elseif ($cat == “D”) { $cat_d += 1; } elseif ($cat == “E”) { $cat_e += 1; } }

Next set a variable equal to the array of categories and set a separate variable that you will be using for the string to null:

$array = array(‘A’ => $cat_a, ‘B’ => $cat_b, ‘C’ => $cat_c, ‘D’ => $cat_d, ‘E’ => $cat_e); $str = “”;

Next you will create a foreach loop that will check the value of each category and either add it to your string variable or discard it. Here you will set up parameters of what qualifies as a category result. If the user selected 6 or more answers in the same category, then that is their category result, otherwise if they selected 2 or more answers in the same category, then that will be one of their category results.

foreach ($array as $i => $value) { if ($value >= 6) { $str = $i; break; } elseif ($value >= 2) { $str .= $i; } }

After you have completed the foreach loop, your $str variable should have a value equal to a category result such as AB, BCD or E. Next you will retrieve the result from your quiz_map table based on the category result:

$query = “SELECT result FROM quiz_map WHERE category_result = ‘$str’ LIMIT 1”; $result = mysql_query($query); $row = mysql_fetch_row($result); var_dump($row);

Test your form to see if the correct result displays. If you run into issues, try incorporating echo statements throughout your query to see if the variables are populating correctly. If everything looks good, its time to incorporate AJAX to display the results without reloading the page.


Change the last line of your quiz.php from ‘var_dump($row);’ to ‘echo json_encode($row);’ Next create a new file in your project directory called demo.js. This is going to contain all of the code responsible for submitting the form data using AJAX.

$(function() { // Get the form. var form = $(‘#quiz’); // Get the results div. var formMessages = $(‘#result’);

Here you have created two new variables that reference the form ID and the result div ID. Next you will set up an event listener for the contact form that will stop the browser from submitting the form. Use the jQuery serialize method to serialize the form data and store the result in a variable called formData.

$(form).submit(function(e) { e.preventDefault(); var formData = $(form).serialize();

Next you will be sending the form date to the server and processing the response:

$.ajax({ type: ‘POST’, url: $(form).attr(‘action’), data: formData, dataType: “json” })

Next you will set up the successful response from the server as well as the failed response. :

.done(function(response) { $(formMessages).text(response); }) .fail(function(data) { $(‘#error’).removeClass(“hide”); }); });

Finally create two <script> elements in your HTML that reference the jquery and the demo.js file. Add these just before the closing </body> tag. Make sure you load jQuerybefore your demo.js file.

<script src=”jquery.js”></script> <script src=”demo.js”></script>

You are all set to go! If you are experiencing issues with certain results, check your tables to make sure there are no special characters. These will cause the form submit to fail. There are some additional bells and whistles that I would recommend adding to your form to make it 2 Legit 2 Quit:





Feel free to reach out to me at heidi [at] or tweet at @swisswebmiss. If you want to contribute to this project, please check out our repository on GitHub.

[Originally published on]



Heidi Olsen

Senior Developer by day, Fun Professional by night