An interactive PHP quiz platform with dynamic question loading, real-time scoring, and a modern glassmorphism UI.
Quiz Academy is a full-stack PHP web application that provides a dynamic quiz experience for students and educators. Users authenticate via a secure login system, select from multiple subjects, answer questions loaded dynamically from a MySQL database, and receive instant scored feedback with visual highlights of correct and incorrect answers. Results are persisted for tracking performance over time.
| Feature | Description |
|---|---|
| π Secure Authentication | Session-based login with prepared statements (SQL injection protection) |
| π Dynamic Subjects | Subjects are fetched from the database β add new topics without code changes |
| β Question Engine | Multiple-choice questions with randomized answer options per subject |
| β Instant Scoring | Real-time score calculation on submission with percentage display |
| π¨ Visual Feedback | Green/red highlights with β/β icons for correct/incorrect answers |
| πΎ Score Persistence | Results saved to database with date tracking for grade analytics |
| π€ User Profile | Displays user email, group info, and personalized welcome |
| π± Responsive Design | Fully responsive layout adapting to mobile, tablet, and desktop |
| Login Page | Quiz Interface |
![]() |
![]() |
The login page features a glassmorphism design with animated gradients, while the quiz interface offers a clean card-based layout with intuitive subject selection.
quizAcademy/
βββ index.php # Login page β authentication & session management
βββ quiz.php # Quiz engine β question rendering, scoring & results
βββ connexion.php # PDO connection, session config, security headers & CSRF helpers
βββ logout.php # Secure session destruction & logout
βββ migration.sql # Database migration for security upgrades
βββ style/
β βββ login.css # Glassmorphism login UI with animations
β βββ style.css # Quiz interface β cards, buttons, responsive layout
βββ images/
β βββ Q-A.png # App logo / favicon
β βββ Logo.png # Alternate logo
β βββ Q-A_Logo.png # Compact logo variant
βββ README.md
graph TD
A[π User visits index.php] --> B{Authenticated?}
B -- No --> C[π Show Login Form]
C --> D[Submit Credentials]
D --> E{Valid User?}
E -- No --> F[β Show Error Message]
F --> C
E -- Yes --> G[π Create Session & Redirect]
B -- Yes --> G
G --> H[π quiz.php β Show Subjects]
H --> I[π Select a Subject]
I --> J[β Load Questions from DB]
J --> K[π Display Quiz Form]
K --> L[βοΈ Submit Answers]
L --> M[βοΈ Calculate Score]
M --> N[πΎ Save Score to DB]
N --> O[π Display Results with Feedback]
O --> H
The application uses a MySQL database named quizacademy with the following structure:
-- Users table
CREATE TABLE users (
userId INT AUTO_INCREMENT PRIMARY KEY,
userName VARCHAR(100) NOT NULL UNIQUE,
userPassword VARCHAR(255) NOT NULL,
userEmail VARCHAR(255),
userGroupe VARCHAR(100)
);
-- Subjects table
CREATE TABLE subjects (
subjectId INT AUTO_INCREMENT PRIMARY KEY,
subjectName VARCHAR(255) NOT NULL
);
-- Questions table
CREATE TABLE questions (
questionId INT AUTO_INCREMENT PRIMARY KEY,
questionName TEXT NOT NULL,
subjectId INT NOT NULL,
FOREIGN KEY (subjectId) REFERENCES subjects(subjectId)
);
-- Answers table
CREATE TABLE answers (
answerId INT AUTO_INCREMENT PRIMARY KEY,
answerName TEXT NOT NULL,
isCorrect TINYINT(1) DEFAULT 0,
questionId INT NOT NULL,
FOREIGN KEY (questionId) REFERENCES questions(questionId)
);
-- Scores table
CREATE TABLE scores (
scoreId INT AUTO_INCREMENT PRIMARY KEY,
subjectId INT NOT NULL,
note DECIMAL(5,2) NOT NULL,
examDate DATE NOT NULL,
FOREIGN KEY (subjectId) REFERENCES subjects(subjectId)
);erDiagram
USERS {
int userId PK
varchar userName
varchar userPassword
varchar userEmail
varchar userGroupe
}
SUBJECTS {
int subjectId PK
varchar subjectName
}
QUESTIONS {
int questionId PK
text questionName
int subjectId FK
}
ANSWERS {
int answerId PK
text answerName
tinyint isCorrect
int questionId FK
}
SCORES {
int scoreId PK
int subjectId FK
decimal note
date examDate
}
SUBJECTS ||--o{ QUESTIONS : "has"
QUESTIONS ||--o{ ANSWERS : "has"
SUBJECTS ||--o{ SCORES : "tracks"
| Layer | Technology | Purpose |
|---|---|---|
| Backend | PHP 8.x | Server-side logic, authentication, quiz engine |
| Database | MySQL | Data persistence (via PDO with prepared statements) |
| Frontend | HTML5 + CSS3 | Semantic markup & modern styling |
| Styling | Custom CSS | Glassmorphism, gradients, animations, responsive design |
| Fonts | Google Fonts (Poppins) | Clean, modern typography |
| Icons | Font Awesome 6 | UI icons throughout the interface |
| Server | XAMPP (Apache) | Local development environment |
- XAMPP (or any Apache + PHP + MySQL stack)
- PHP 8.0+ (uses
str_starts_with,password_hash, named arguments) - MySQL 5.7+ or MariaDB 10.x+
-
Clone the repository
git clone https://github.com/YassirKz/QuizAcademy.git
-
Move to your web server directory
# For XAMPP on Windows: mv QuizAcademy C:\xampp\htdocs\quizAcademy # For XAMPP on macOS/Linux: mv QuizAcademy /opt/lampp/htdocs/quizAcademy
-
Create the database
- Open phpMyAdmin at
http://localhost/phpmyadmin - Create a new database named
quizacademy - Import the SQL schema above, or run the
CREATE TABLEstatements manually
- Open phpMyAdmin at
-
Seed sample data
-- Add a subject INSERT INTO subjects (subjectName) VALUES ('General Knowledge'); -- Add a question INSERT INTO questions (questionName, subjectId) VALUES ('What is the capital of France?', 1); -- Add answers (mark one as correct) INSERT INTO answers (answerName, isCorrect, questionId) VALUES ('London', 0, 1); INSERT INTO answers (answerName, isCorrect, questionId) VALUES ('Paris', 1, 1); INSERT INTO answers (answerName, isCorrect, questionId) VALUES ('Berlin', 0, 1); INSERT INTO answers (answerName, isCorrect, questionId) VALUES ('Madrid', 0, 1); -- Add a user INSERT INTO users (userName, userPassword, userEmail, userGroupe) VALUES ('admin', 'admin123', 'admin@quiz.com', 'Group A');
-
Configure database connection (if needed)
Edit
connexion.php:$host = 'localhost'; $dbName = 'quizacademy'; $dbUsername = 'root'; $dbPassword = ''; // Set your MySQL password if applicable
-
Launch the application
- Start Apache and MySQL in XAMPP
- Navigate to
http://localhost/quizAcademy/ - Login with your seeded credentials
| Concern | Status | Implementation |
|---|---|---|
| SQL Injection | β Protected | PDO prepared statements with EMULATE_PREPARES = false |
| Password Hashing | β Protected | password_hash() (bcrypt) + auto-upgrade from plain text |
| XSS Prevention | β Protected | htmlspecialchars() on all outputs |
| CSRF Protection | β Protected | Token-based validation on all forms |
| Session Fixation | β Protected | session_regenerate_id(true) on login |
| Session Cookies | β Hardened | httponly, samesite=Strict, strict_mode |
| Brute Force | β Protected | Rate limiting (5 attempts β 5 min lockout) |
| HTTP Headers | β Set | X-Content-Type-Options, X-Frame-Options, X-XSS-Protection |
| Logout | β Implemented | Full session destruction + cookie removal |
| Score Integrity | β Linked | Scores tied to authenticated userId |
Note: Run
migration.sqlin phpMyAdmin to apply the database schema changes (addsuserIdto scores, expands password column for bcrypt).
- π Password hashing with
bcrypt - π‘οΈ CSRF token protection on all forms
- π Session hardening & logout
- π« Brute force rate limiting
- π Student dashboard with score history & analytics
- β±οΈ Timed quizzes with countdown timer
- π² Randomized question order
- π¨βπ« Admin panel for managing subjects, questions & answers
- π€ Export results to CSV/PDF
- π Dark mode toggle
- π Multi-language support (FR/EN/AR)
Contributions are welcome! Here's how:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
This project is open source and available under the MIT License.
Yassir Kz β @YassirKz
Made with β€οΈ for education


