0% found this document useful (0 votes)
26 views10 pages

PHP MySQL Question Paper System

The document describes a Simple Question Paper Setting System built using PHP and MySQL, detailing its components and usage instructions. It includes files for database connection, user authentication via OTP, and functionalities for creating and managing question papers. The system is designed to be minimal and secure, with recommendations for enhancements in a production environment.

Uploaded by

ang.jeevan
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views10 pages

PHP MySQL Question Paper System

The document describes a Simple Question Paper Setting System built using PHP and MySQL, detailing its components and usage instructions. It includes files for database connection, user authentication via OTP, and functionalities for creating and managing question papers. The system is designed to be minimal and secure, with recommendations for enhancements in a production environment.

Uploaded by

ang.jeevan
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

# Question Paper Setting System (PHP + MySQL)

This single-file repository contains multiple files separated by headers. Save each
header-block into its own file in your project folder.

---

## [Link]

```
Simple Question Paper Setting System (PHP + MySQL)

Requirements:
- PHP 7.4+ with mysqli
- MySQL / MariaDB
- A mail or SMS gateway for OTP (this sample uses session-based OTP for demo)

Files:
- db_connect.php -- DB connection
- sql_schema.sql -- SQL schema to create necessary tables
- invigilator_login.php -- Login page (mobile + OTP)
- send_otp.php -- Generates and "sends" OTP (demo)
- verify_otp.php -- Verifies OTP and logs user in
- [Link] -- Main dashboard (choose action)
- create_paper.php -- Form to create a question paper
- save_paper.php -- Saves paper & questions
- view_papers.php -- List and view created papers
- [Link] -- Logout
- assets/[Link] -- Basic CSS

Usage:
1. Create database and import sql_schema.sql
2. Update db_connect.php with DB credentials
3. Place files in your webroot and open invigilator_login.php

NOTE: This is a straightforward, minimal, and secure-by-design example. For


production, add rate-limiting, proper SMS gateway, CSRF tokens, stronger auth,
input validation, and HTTPS.
```

---

## sql_schema.sql

```
CREATE DATABASE IF NOT EXISTS qpaper_db CHARACTER SET utf8mb4 COLLATE
utf8mb4_unicode_ci;
USE qpaper_db;

-- users (invigilators) table


CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
mobile VARCHAR(15) UNIQUE NOT NULL,
name VARCHAR(100) DEFAULT NULL,
role ENUM('invigilator','admin') DEFAULT 'invigilator',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

-- otp store (short-lived)


CREATE TABLE IF NOT EXISTS otps (
id INT AUTO_INCREMENT PRIMARY KEY,
mobile VARCHAR(15) NOT NULL,
otp_code VARCHAR(10) NOT NULL,
expires_at DATETIME NOT NULL,
used TINYINT(1) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX(mobile)
) ENGINE=InnoDB;

-- subjects
CREATE TABLE IF NOT EXISTS subjects (
id INT AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(20) NOT NULL,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

-- papers
CREATE TABLE IF NOT EXISTS papers (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
category VARCHAR(50) NOT NULL, -- e.g., Question Paper, Paper Correction
exam_month VARCHAR(50) NOT NULL,
subject_id INT NOT NULL,
created_by INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (subject_id) REFERENCES subjects(id) ON DELETE CASCADE,
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
) ENGINE=InnoDB;

-- questions
CREATE TABLE IF NOT EXISTS questions (
id INT AUTO_INCREMENT PRIMARY KEY,
paper_id INT NOT NULL,
qtext TEXT NOT NULL,
marks INT DEFAULT 1,
qtype ENUM('mcq','short','long','file') DEFAULT 'short',
extra JSON NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (paper_id) REFERENCES papers(id) ON DELETE CASCADE
) ENGINE=InnoDB;

-- sample subject
INSERT INTO subjects (code, name) VALUES
('CS101','Computer Science - Fundamentals'),
('MA101','Mathematics - Calculus');

-- sample admin user (you can change mobile)


INSERT INTO users (mobile, name, role) VALUES
('9999999999','Admin User','admin');
```

---

## db_connect.php

```
<?php
$DB_HOST = '[Link]';
$DB_USER = 'root';
$DB_PASS = '';
$DB_NAME = 'qpaper_db';

$conn = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME);


if ($conn->connect_error) {
die('DB Connect Error: ' . $conn->connect_error);
}
$conn->set_charset('utf8mb4');
```

---

## assets/[Link]

```
body { font-family: Arial, Helvetica, sans-serif; background:#f7f7f9; color:#222 }
.container{max-width:900px;margin:30px auto;padding:20px;background:#fff;border-
radius:8px;box-shadow:0 6px 18px rgba(0,0,0,0.06)}
.field{margin-bottom:12px}
label{display:block;margin-bottom:6px;font-weight:600}
input[type=text], input[type=tel], select,
textarea{width:100%;padding:8px;border:1px solid #ddd;border-radius:4px}
button{padding:10px 14px;border:none;border-
radius:6px;background:#0b79d0;color:white;cursor:pointer}
.table{width:100%;border-collapse:collapse}
.table th, .table td{border:1px solid #e6e6e6;padding:8px}

.header {display:flex;justify-content:space-between;align-items:center}

.small{font-size:0.9em;color:#555}
```

---

## invigilator_login.php

```
<?php
session_start();
require 'db_connect.php';
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Invigilator Login - QPaper</title>
<link rel="stylesheet" href="assets/[Link]">
</head>
<body>
<div class="container">
<div class="header"><h2>Choose Category</h2><div class="small">Question Paper |
Paper Correction | Invigilator</div></div>
<form action="send_otp.php" method="post">
<div class="field">
<label>Choose Exam Month</label>
<select name="exam_month">
<option value="Jan 2026">Jan 2026</option>
<option value="Feb 2026">Feb 2026</option>
<option value="Mar 2026">Mar 2026</option>
</select>
</div>
<div class="field">
<label>Mobile Number</label>
<input type="tel" name="mobile" placeholder="Enter mobile" required>
</div>
<div class="field">
<button type="submit">Send OTP</button>
</div>
</form>
<hr>
<form action="verify_otp.php" method="post">
<div class="field">
<label>Enter OTP</label>
<input type="text" name="otp" placeholder="6 digit OTP">
<input type="hidden" name="mobile" id="mobile_hidden">
</div>
<div class="field">
<button type="submit">Verify OTP</button>
</div>
</form>
</div>
</body>
</html>
```

---

## send_otp.php

```
<?php
session_start();
require 'db_connect.php';

$mobile = $conn->real_escape_string($_POST['mobile'] ?? '');


$exam_month = $conn->real_escape_string($_POST['exam_month'] ?? '');
if (!$mobile) { header('Location: invigilator_login.php'); exit; }

// Generate 6-digit OTP


$otp = str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
$expires = (new DateTime('+5 minutes'))->format('Y-m-d H:i:s');

$stmt = $conn->prepare('INSERT INTO otps (mobile, otp_code, expires_at) VALUES


(?, ?, ?)');
$stmt->bind_param('sss', $mobile, $otp, $expires);
$stmt->execute();

// For demo: store OTP in session so user can see in verify page. In prod, send via
SMS gateway.
$_SESSION['last_otp_mobile'] = $mobile;
$_SESSION['last_otp_code'] = $otp;
$_SESSION['last_otp_expires'] = $expires;

// Ensure user exists in users table


$u = $conn->prepare('SELECT id FROM users WHERE mobile=?');
$u->bind_param('s', $mobile);
$u->execute();
$res = $u->get_result();
if ($res->num_rows === 0) {
$ins = $conn->prepare('INSERT INTO users (mobile) VALUES (?)');
$ins->bind_param('s', $mobile);
$ins->execute();
}

// redirect back to login with a small notice (demo shows OTP)


header('Location: invigilator_login.php');
exit;
```

---

## verify_otp.php

```
<?php
session_start();
require 'db_connect.php';
$mobile = $conn->real_escape_string($_POST['mobile'] ??
($_SESSION['last_otp_mobile'] ?? ''));
$otp = $conn->real_escape_string($_POST['otp'] ?? '');

if (!$mobile || !$otp) {
header('Location: invigilator_login.php'); exit;
}

$st = $conn->prepare('SELECT id, otp_code, expires_at, used FROM otps WHERE


mobile=? ORDER BY id DESC LIMIT 1');
$st->bind_param('s', $mobile);
$st->execute();
$r = $st->get_result();
if ($r->num_rows === 0) { header('Location: invigilator_login.php'); exit; }
$row = $r->fetch_assoc();

if ($row['used']) { die('OTP already used'); }


if ($row['otp_code'] !== $otp) { die('Invalid OTP'); }
if (new DateTime() > new DateTime($row['expires_at'])) { die('OTP expired'); }

// Mark used
$u = $conn->prepare('UPDATE otps SET used=1 WHERE id=?');
$u->bind_param('i', $row['id']); $u->execute();

// Log user in: fetch user id


$uq = $conn->prepare('SELECT id, name FROM users WHERE mobile=? LIMIT 1');
$uq->bind_param('s', $mobile); $uq->execute();
$ur = $uq->get_result();
$user = $ur->fetch_assoc();

$_SESSION['user_id'] = $user['id'];
$_SESSION['user_mobile'] = $mobile;
$_SESSION['user_name'] = $user['name'] ?? 'Invigilator';

header('Location: [Link]');
exit;
```
---

## [Link]

```
<?php
session_start();
require 'db_connect.php';
if (empty($_SESSION['user_id'])) { header('Location: invigilator_login.php'); exit;
}

$user_id = (int)$_SESSION['user_id'];

// load subjects
$subs = $conn->query('SELECT * FROM subjects ORDER BY name');
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Dashboard</title>
<link rel="stylesheet" href="assets/[Link]">
</head>
<body>
<div class="container">
<div class="header"><h2>Welcome, <?= htmlspecialchars($_SESSION['user_name']) ?
></h2>
<div><a href="view_papers.php">View Papers</a> | <a
href="create_paper.php">Create Paper</a> | <a href="[Link]">Logout</a></div>
</div>
<p class="small">Choose subject & start creating question paper.</p>
<form action="create_paper.php" method="get">
<div class="field">
<label>Choose Subject</label>
<select name="subject_id">
<?php while($s=$subs->fetch_assoc()): ?>
<option value="<?= $s['id'] ?>"><?= htmlspecialchars($s['code'] . ' - ' .
$s['name']) ?></option>
<?php endwhile; ?>
</select>
</div>
<div class="field">
<button type="submit">Create Paper for Selected Subject</button>
</div>
</form>
</div>
</body>
</html>
```

---

## create_paper.php

```
<?php
session_start();
require 'db_connect.php';
if (empty($_SESSION['user_id'])) { header('Location: invigilator_login.php'); exit;
}

$subject_id = intval($_GET['subject_id'] ?? 0);


$sub = null;
if ($subject_id) {
$q = $conn->prepare('SELECT * FROM subjects WHERE id=?');
$q->bind_param('i', $subject_id); $q->execute(); $res = $q->get_result();
$sub = $res->fetch_assoc();
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Create Paper</title>
<link rel="stylesheet" href="assets/[Link]">
</head>
<body>
<div class="container">
<h3>Create Paper <?= $sub ? '- ' . htmlspecialchars($sub['name']) : '' ?></h3>
<form action="save_paper.php" method="post">
<input type="hidden" name="subject_id" value="<?= $subject_id ?>">
<div class="field"><label>Paper Title</label><input type="text" name="title"
required></div>
<div class="field"><label>Category</label>
<select name="category">
<option>Question Paper</option>
<option>Paper Correction</option>
</select>
</div>
<div class="field"><label>Exam Month</label><input type="text"
name="exam_month" placeholder="e.g. Nov 2026"></div>

<hr>
<h4>Questions</h4>
<div id="questions">
<div class="qblock">
<label>Question 1</label>
<textarea name="qtext[]" rows="3" required></textarea>
<div class="field"><label>Marks</label><input type="number" name="marks[]"
value="1"></div>
<div class="field"><label>Type</label>
<select name="qtype[]"><option value="short">Short</option><option
value="long">Long</option><option value="mcq">MCQ</option></select>
</div>
</div>
</div>
<div class="field"><button type="button" onclick="addQuestion()">Add Another
Question</button></div>
<div class="field"><button type="submit">Save Paper</button></div>
</form>
</div>
<script>
let qcount=1;
function addQuestion(){ qcount++; const div=[Link]('div');
[Link]='qblock'; [Link]=`<label>Question ${qcount}</label><textarea
name="qtext[]" rows="3" required></textarea><div
class="field"><label>Marks</label><input type="number" name="marks[]"
value="1"></div><div class="field"><label>Type</label><select
name="qtype[]"><option value="short">Short</option><option
value="long">Long</option><option value="mcq">MCQ</option></select></div>`;
[Link]('questions').appendChild(div); }
</script>
</body>
</html>
```

---

## save_paper.php

```
<?php
session_start();
require 'db_connect.php';
if (empty($_SESSION['user_id'])) { header('Location: invigilator_login.php'); exit;
}

$title = $conn->real_escape_string($_POST['title'] ?? 'Untitled');


$category = $conn->real_escape_string($_POST['category'] ?? 'Question Paper');
$exam_month = $conn->real_escape_string($_POST['exam_month'] ?? '');
$subject_id = intval($_POST['subject_id'] ?? 0);
$created_by = intval($_SESSION['user_id']);

if (!$subject_id) { die('Subject required'); }

$stmt = $conn->prepare('INSERT INTO papers (title, category, exam_month,


subject_id, created_by) VALUES (?, ?, ?, ?, ?)');
$stmt->bind_param('sssis', $title, $category, $exam_month, $subject_id,
$created_by);
$stmt->execute();
$paper_id = $stmt->insert_id;

// save questions
$qtexts = $_POST['qtext'] ?? [];
$marks = $_POST['marks'] ?? [];\$qtypes = $_POST['qtype'] ?? [];
for ($i=0;$i<count($qtexts);$i++){
$qt = $conn->real_escape_string($qtexts[$i]);
$mk = intval($marks[$i] ?? 1);
$qtpe = $conn->real_escape_string($qtypes[$i] ?? 'short');
$ins = $conn->prepare('INSERT INTO questions (paper_id, qtext, marks, qtype)
VALUES (?, ?, ?, ?)');
$ins->bind_param('isis', $paper_id, $qt, $mk, $qtpe);
$ins->execute();
}

header('Location: view_papers.php?created=1');
exit;
```

---

## view_papers.php

```
<?php
session_start();
require 'db_connect.php';
if (empty($_SESSION['user_id'])) { header('Location: invigilator_login.php'); exit;
}

$papers = $conn->query('SELECT p.*, [Link] AS scode, [Link] AS sname FROM papers p


JOIN subjects s ON p.subject_id=[Link] ORDER BY p.created_at DESC');
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>View Papers</title>
<link rel="stylesheet" href="assets/[Link]">
</head>
<body>
<div class="container">
<div class="header"><h2>Saved Papers</h2><div><a
href="[Link]">Dashboard</a> | <a href="[Link]">Logout</a></div></div>
<table class="table">
<thead><tr><th>ID</th><th>Title</th><th>Subject</th><th>Category</
th><th>Created</th><th>Action</th></tr></thead>
<tbody>
<?php while($p=$papers->fetch_assoc()): ?>
<tr>
<td><?= $p['id'] ?></td>
<td><?= htmlspecialchars($p['title']) ?></td>
<td><?= htmlspecialchars($p['scode'] . ' - ' . $p['sname']) ?></td>
<td><?= htmlspecialchars($p['category']) ?></td>
<td><?= $p['created_at'] ?></td>
<td><a href="view_paper_detail.php?id=<?= $p['id'] ?>">View</a></td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
</body>
</html>
```

---

## view_paper_detail.php

```
<?php
session_start(); require 'db_connect.php';
if (empty($_SESSION['user_id'])) { header('Location: invigilator_login.php'); exit;
}
$id = intval($_GET['id'] ?? 0);
$stmt = $conn->prepare('SELECT p.*, [Link] AS scode, [Link] AS sname FROM papers p
JOIN subjects s ON p.subject_id=[Link] WHERE [Link]=?');
$stmt->bind_param('i',$id); $stmt->execute(); $res = $stmt->get_result();
$paper = $res->fetch_assoc(); if (!$paper) die('Not found');
$qs = $conn->prepare('SELECT * FROM questions WHERE paper_id=? ORDER BY id'); $qs-
>bind_param('i',$id); $qs->execute(); $qres = $qs->get_result();
?>
<!doctype html>
<html><head><meta charset="utf-8"><title>Paper <?=
htmlspecialchars($paper['title']) ?></title><link rel="stylesheet"
href="assets/[Link]"></head><body>
<div class="container">
<div class="header"><h2><?= htmlspecialchars($paper['title']) ?></h2><div><a
href="view_papers.php">Back</a></div></div>
<p><strong>Subject:</strong> <?= htmlspecialchars($paper['scode'].' - '.
$paper['sname']) ?> | <strong>Category:</strong> <?=
htmlspecialchars($paper['category']) ?></p>
<hr>
<?php $i=1; while($q=$qres->fetch_assoc()): ?>
<div><strong>Q<?= $i ?> (<?= $q['marks'] ?> marks)</strong>
<p><?= nl2br(htmlspecialchars($q['qtext'])) ?></p></div>
<hr>
<?php $i++; endwhile; ?>
</div>
</body></html>
```

---

## [Link]

```
<?php
session_start(); session_unset(); session_destroy(); header('Location:
invigilator_login.php');
```

---

End of files.

You might also like