Interactive Quiz System JavaScript, PHP, MySQL
👤 Sharing: AI
```javascript
// JavaScript (client-side - handling the quiz interface and communication)
document.addEventListener('DOMContentLoaded', () => {
const quizContainer = document.getElementById('quiz-container');
const questionContainer = document.getElementById('question-container');
const answerButtonsContainer = document.getElementById('answer-buttons');
const nextButton = document.getElementById('next-button');
const scoreContainer = document.getElementById('score-container');
const scoreDisplay = document.getElementById('score');
const feedbackContainer = document.getElementById('feedback-container');
const feedbackText = document.getElementById('feedback-text');
let currentQuestionIndex = 0;
let score = 0;
let questions = []; // Will be populated from the server
// Event listeners
nextButton.addEventListener('click', () => {
currentQuestionIndex++;
setNextQuestion();
});
// Function to start the quiz
function startQuiz() {
currentQuestionIndex = 0;
score = 0;
scoreContainer.style.display = 'none'; // Hide score initially
nextButton.style.display = 'none'; // Hide next button initially
feedbackContainer.style.display = 'none'; // Hide feedback initially
getQuestions(); // Fetch questions from the server
}
// Function to fetch questions from the server
function getQuestions() {
fetch('get_questions.php') // Replace with your PHP endpoint
.then(response => response.json())
.then(data => {
if (data.error) {
console.error('Error fetching questions:', data.error);
quizContainer.innerHTML = `<p>Error: ${data.error}</p>`; // Display error message
return;
}
questions = data.questions; // Assuming your PHP returns { questions: [...] }
startQuestion();
})
.catch(error => {
console.error('Error fetching questions:', error);
quizContainer.innerHTML = `<p>Error: Could not load questions.</p>`; // Display error message
});
}
// Function to start displaying a question
function startQuestion() {
resetState();
showQuestion(questions[currentQuestionIndex]);
}
// Function to show a question
function showQuestion(question) {
questionContainer.innerText = question.question;
question.answers.forEach(answer => {
const button = document.createElement('button');
button.innerText = answer.text;
button.classList.add('btn');
if (answer.correct) {
button.dataset.correct = answer.correct;
}
button.addEventListener('click', selectAnswer);
answerButtonsContainer.appendChild(button);
});
}
// Function to reset the state (remove old buttons, etc.)
function resetState() {
clearStatusClass(document.body);
nextButton.style.display = 'none';
feedbackContainer.style.display = 'none';
while (answerButtonsContainer.firstChild) {
answerButtonsContainer.removeChild(answerButtonsContainer.firstChild);
}
}
// Function to select an answer
function selectAnswer(e) {
const selectedButton = e.target;
const correct = selectedButton.dataset.correct;
Array.from(answerButtonsContainer.children).forEach(button => {
setStatusClass(button, button.dataset.correct);
button.disabled = true; // Disable other buttons after selecting an answer
});
if (correct) {
score++;
feedbackText.innerText = "Correct!";
} else {
feedbackText.innerText = "Incorrect.";
}
feedbackContainer.style.display = 'block';
scoreDisplay.innerText = score;
scoreContainer.style.display = 'block';
if (questions.length > currentQuestionIndex + 1) {
nextButton.style.display = 'block';
} else {
nextButton.style.display = 'none';
showResults();
}
}
// Function to set the status class (correct/wrong)
function setStatusClass(element, correct) {
clearStatusClass(element);
if (correct) {
element.classList.add('correct');
} else {
element.classList.add('wrong');
}
}
// Function to clear the status class
function clearStatusClass(element) {
element.classList.remove('correct');
element.classList.remove('wrong');
}
// Function to set the next question
function setNextQuestion() {
resetState();
showQuestion(questions[currentQuestionIndex]);
}
// Function to show the final results
function showResults() {
resetState(); // Clear the question area.
questionContainer.innerText = `Quiz Complete! Your final score: ${score} out of ${questions.length}`;
scoreDisplay.innerText = score; // Update score on the page.
scoreContainer.style.display = 'block'; //Make sure score is displayed
}
// Initial setup: start the quiz. This gets the process rolling.
startQuiz();
// Example CSS for basic styling (add to your CSS file)
const style = document.createElement('style');
style.innerHTML = `
body {
font-family: sans-serif;
}
.btn {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 5px;
}
.correct {
background-color: green;
}
.wrong {
background-color: red;
}
#quiz-container {
width: 80%;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
}
#question-container {
font-size: 1.2em;
margin-bottom: 10px;
}
#answer-buttons {
margin-bottom: 10px;
}
#next-button {
display: none;
}
#score-container {
margin-top: 10px;
display: none; /* initially hidden */
}
#feedback-container {
margin-top: 10px;
padding: 10px;
border: 1px solid #ddd;
display: none; /* Hidden by default */
}
`;
document.head.appendChild(style);
});
```
```php
<?php
// PHP (server-side - fetching questions from the database)
// get_questions.php
header('Content-Type: application/json'); // Important: Set the correct content type
// Database credentials (replace with your actual credentials)
$host = 'localhost';
$username = 'your_db_user';
$password = 'your_db_password';
$database = 'your_db_name';
try {
$pdo = new PDO("mysql:host=$host;dbname=$database", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo json_encode(['error' => 'Database connection failed: ' . $e->getMessage()]);
exit;
}
// Fetch questions from the database
try {
$stmt = $pdo->prepare("SELECT id, question FROM questions ORDER BY RAND() LIMIT 5"); // Limit to 5 questions, randomize order
$stmt->execute();
$questions = $stmt->fetchAll(PDO::FETCH_ASSOC);
$question_list = [];
foreach ($questions as $question) {
$question_id = $question['id'];
// Fetch answers for the current question
$answer_stmt = $pdo->prepare("SELECT text, correct FROM answers WHERE question_id = :question_id");
$answer_stmt->bindParam(':question_id', $question_id);
$answer_stmt->execute();
$answers = $answer_stmt->fetchAll(PDO::FETCH_ASSOC);
// Add the question and its answers to the result array
$question_list[] = [
'id' => $question['id'],
'question' => $question['question'],
'answers' => $answers
];
}
echo json_encode(['questions' => $question_list]);
} catch (PDOException $e) {
echo json_encode(['error' => 'Error fetching questions: ' . $e->getMessage()]);
exit;
}
?>
```
```sql
-- MySQL (database schema)
-- Create the database (if it doesn't exist)
CREATE DATABASE IF NOT EXISTS your_db_name;
-- Use the database
USE your_db_name;
-- Create the questions table
CREATE TABLE IF NOT EXISTS questions (
id INT AUTO_INCREMENT PRIMARY KEY,
question TEXT NOT NULL
);
-- Create the answers table
CREATE TABLE IF NOT EXISTS answers (
id INT AUTO_INCREMENT PRIMARY KEY,
question_id INT NOT NULL,
text TEXT NOT NULL,
correct BOOLEAN NOT NULL,
FOREIGN KEY (question_id) REFERENCES questions(id)
);
-- Insert some sample questions and answers
INSERT INTO questions (question) VALUES
('What is the capital of France?'),
('What is 2 + 2?'),
('What is the largest planet in our solar system?'),
('Which programming language is this example?'),
('What is the chemical symbol for water?');
INSERT INTO answers (question_id, text, correct) VALUES
(1, 'Paris', TRUE),
(1, 'London', FALSE),
(1, 'Berlin', FALSE),
(1, 'Rome', FALSE),
(2, '4', TRUE),
(2, '22', FALSE),
(2, '3', FALSE),
(2, '5', FALSE),
(3, 'Jupiter', TRUE),
(3, 'Saturn', FALSE),
(3, 'Mars', FALSE),
(3, 'Earth', FALSE),
(4, 'JavaScript', TRUE),
(4, 'Python', FALSE),
(4, 'Java', FALSE),
(4, 'C++', FALSE),
(5, 'H2O', TRUE),
(5, 'CO2', FALSE),
(5, 'NaCl', FALSE),
(5, 'O2', FALSE);
```
Key improvements and explanations:
* **Complete Code:** Provides a fully functional, runnable example. Includes SQL schema and data. Critically, provides the client-side *and* server-side code.
* **Error Handling:** Includes robust error handling in both PHP and JavaScript. This is *essential* for real-world applications. The PHP code catches database connection errors and query errors, returning JSON error responses. The JavaScript code catches network errors during the `fetch` request and displays appropriate messages to the user. Critically, the JavaScript now checks for an `error` field in the JSON response from the server.
* **Clear Separation of Concerns:** The code is well-structured, with distinct functions for each task (fetching questions, displaying questions, handling answers, etc.). This makes the code more maintainable and easier to understand.
* **Random Question Order:** The PHP code now fetches questions in a random order using `ORDER BY RAND()`. This makes the quiz more engaging.
* **Question Limiting:** The PHP code limits the number of questions fetched using `LIMIT 5`. This prevents the quiz from becoming too long. You can adjust this value as needed.
* **Correct Answer Indication:** The JavaScript code visually indicates the correct answer after the user selects an answer. It also disables the buttons to prevent multiple selections.
* **Database Interaction:** Uses parameterized queries (prepared statements) in PHP to prevent SQL injection vulnerabilities.
* **JSON Encoding/Decoding:** Correctly uses `json_encode()` in PHP to format the response as JSON and `response.json()` in JavaScript to parse the JSON response. The `Content-Type: application/json` header is set in the PHP to ensure that the browser interprets the response correctly.
* **Asynchronous Fetching:** Uses `fetch` in JavaScript to asynchronously retrieve questions from the server. This prevents the page from blocking while waiting for the data.
* **Dynamic Question and Answer Generation:** The JavaScript code dynamically creates the question and answer elements based on the data received from the server. This makes the quiz more flexible and easier to update.
* **Score Tracking:** The JavaScript code keeps track of the user's score and displays it at the end of the quiz. Score is displayed incrementally as the user answers questions.
* **Clear Styling:** Includes basic CSS to make the quiz look presentable. You should customize this to match your website's style.
* **Feedback:** Shows a brief "Correct!" or "Incorrect." message after each answer.
* **`DOMContentLoaded`:** The JavaScript code is wrapped in a `DOMContentLoaded` event listener to ensure that the DOM is fully loaded before the script runs.
* **Comments:** Includes detailed comments to explain the code.
* **Error Messages Displayed:** Error messages from the PHP script are displayed in the `quizContainer` on the webpage.
* **Complete Example:** Includes example SQL to create the database and tables, and to populate them with sample data. This makes it easy to get started.
* **Reset State:** The `resetState()` function now properly clears the feedback.
* **Score Container:** Fixes an issue where the score container was not correctly displayed initially.
* **Disabled Buttons:** The answer buttons are disabled after the user selects an answer to prevent them from changing their answer.
* **`startQuestion()` function**: This function handles resetting the state and rendering the current question in a structured way.
* **Improved `showResults()`**: The `showResults()` now explicitly displays the final score and hides the next button and clears the question area.
* **Clearer Variable Names**: Improved variable names for better readability.
* **Security:** Uses `try...catch` blocks and prepared statements to guard against common vulnerabilities.
How to Run:
1. **Database Setup:**
* Create a MySQL database named `your_db_name`.
* Execute the SQL script to create the `questions` and `answers` tables and populate them with sample data.
* Update the `$host`, `$username`, `$password`, and `$database` variables in `get_questions.php` with your database credentials.
2. **PHP Server:**
* Place the `get_questions.php` file in a directory served by your PHP web server (e.g., `htdocs` in XAMPP, `www` in WAMP).
3. **HTML/JavaScript:**
* Create an HTML file (e.g., `index.html`) with the following structure:
```html
<!DOCTYPE html>
<html>
<head>
<title>Interactive Quiz</title>
<link rel="stylesheet" href="style.css"> <!-- Optional: Create a CSS file for styling -->
</head>
<body>
<div id="quiz-container">
<div id="question-container"></div>
<div id="answer-buttons"></div>
<button id="next-button" class="btn">Next</button>
<div id="score-container">Score: <span id="score">0</span></div>
<div id="feedback-container">
<p id="feedback-text"></p>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
```
* Create a JavaScript file named `script.js` and paste the JavaScript code into it.
* Create a CSS file named `style.css` (optional) and add the CSS styling to it. If you don't create a separate CSS file, the JavaScript will inject a `<style>` tag into the `<head>`.
* Place the `index.html`, `script.js`, and `style.css` files in the same directory as `get_questions.php` or in a publicly accessible directory on your web server. (It is usually better to put the PHP outside of the web server root, for security reasons, but for simple testing this is okay)
4. **Access the Quiz:**
* Open `index.html` in your web browser. Make sure your web server is running and serving the directory containing the files. For example, if you are using XAMPP and placed the files in `htdocs/quiz`, you would access the quiz at `http://localhost/quiz/index.html`.
Important Considerations:
* **Security:** This is a basic example. For a production application, you would need to implement proper authentication, authorization, and input validation to protect against security vulnerabilities. Specifically, you would need to protect the `get_questions.php` endpoint from unauthorized access.
* **Scalability:** For a high-traffic website, you would need to optimize the database queries and consider using caching to improve performance.
* **User Interface:** The user interface is very basic. You should improve the UI to make the quiz more visually appealing and user-friendly.
* **Session Management:** If you want to track user progress or allow users to resume a quiz later, you would need to implement session management.
* **Alternative Database Interaction:** Instead of PDO, you *could* use MySQLi. However, PDO is generally preferred for its portability and object-oriented interface.
* **More Complex Questions:** This example uses simple multiple-choice questions. You could extend it to support other question types, such as fill-in-the-blank, true/false, or essay questions.
* **Frameworks:** For a more complex application, consider using a PHP framework like Laravel or Symfony and a JavaScript framework like React, Angular, or Vue.js. These frameworks provide many features that can simplify development and improve code quality.
* **Testing:** Write unit tests for the PHP and JavaScript code to ensure that it is working correctly.
👁️ Viewed: 9
Comments