Online Exam Result System built with HTML, CSS, JavaScript, PHP, and MySQL.

πŸ“Š Project Introduction: Online Exam Result System

This project is a comprehensive Online Exam Result System designed for educational institutions to publish and manage student exam results online. Students can securely access their results using their roll number and date of birth, while administrators can upload, edit, and manage results efficiently.

The Problem it Solves:
Traditional result publishing involves printing and distributing mark sheets, which is time-consuming, costly, and prone to errors. This digital system allows instant access to results from anywhere, reduces administrative workload, provides secure access, and maintains a permanent digital record of all results.

Key Features:

  • Student Features:
  • Secure result access using roll number and date of birth
  • View detailed subject-wise marks, total marks, percentage, and grade
  • Download result as PDF for printing
  • View result history for previous exams
  • Check rank and comparison with toppers
  • Receive email/SMS notification when results are published
  • Admin Features:
  • Dashboard with statistics (total students, exams, results published)
  • Exam management (create, edit, delete exams)
  • Result upload via manual entry or CSV import
  • Bulk result publishing
  • Student management
  • Generate merit lists and rank cards
  • Export results to Excel/PDF
  • Send bulk notifications to students
  • Analytics and performance reports

Technology Stack:

  • Frontend: HTML5, CSS3, JavaScript (Fetch API, Chart.js for analytics)
  • Backend: PHP (Object-Oriented PHP with PDO)
  • Database: MySQL
  • Additional Libraries:
  • FPDF (PDF generation)
  • PHPSpreadsheet (Excel import/export)
  • PHPMailer (email notifications)

πŸ“ Project File Structure

online-exam-result/
β”‚
β”œβ”€β”€ index.php                 # Homepage - Result search
β”œβ”€β”€ result.php                # Display student result
β”œβ”€β”€ download-result.php       # Download result as PDF
β”œβ”€β”€ login.php                 # Admin login
β”œβ”€β”€ logout.php                # Logout script
β”‚
β”œβ”€β”€ admin/                    # Admin Panel
β”‚   β”œβ”€β”€ index.php             # Admin login redirect
β”‚   β”œβ”€β”€ dashboard.php         # Admin dashboard
β”‚   β”œβ”€β”€ exams.php             # Manage exams
β”‚   β”œβ”€β”€ add-exam.php          # Add new exam
β”‚   β”œβ”€β”€ edit-exam.php         # Edit exam
β”‚   β”œβ”€β”€ delete-exam.php       # Delete exam
β”‚   β”œβ”€β”€ results.php           # Manage results
β”‚   β”œβ”€β”€ add-result.php        # Add single result
β”‚   β”œβ”€β”€ import-results.php    # Bulk import via CSV
β”‚   β”œβ”€β”€ edit-result.php       # Edit result
β”‚   β”œβ”€β”€ delete-result.php     # Delete result
β”‚   β”œβ”€β”€ students.php          # Manage students
β”‚   β”œβ”€β”€ add-student.php       # Add student
β”‚   β”œβ”€β”€ edit-student.php      # Edit student
β”‚   β”œβ”€β”€ reports.php           # Generate reports
β”‚   β”œβ”€β”€ merit-list.php        # Generate merit list
β”‚   β”œβ”€β”€ settings.php          # System settings
β”‚   └── logout.php            # Admin logout
β”‚
β”œβ”€β”€ includes/                  # Backend logic
β”‚   β”œβ”€β”€ config.php             # Database connection
β”‚   β”œβ”€β”€ functions.php          # Helper functions
β”‚   β”œβ”€β”€ auth.php               # Admin authentication
β”‚   └── pdf_generator.php      # PDF generation functions
β”‚
β”œβ”€β”€ api/                        # AJAX endpoints
β”‚   β”œβ”€β”€ check-result.php       # Check if result exists
β”‚   β”œβ”€β”€ get-student-details.php # Get student details
β”‚   └── send-notification.php   # Send result notification
β”‚
β”œβ”€β”€ assets/                    # Static assets
β”‚   β”œβ”€β”€ css/
β”‚   β”‚   β”œβ”€β”€ style.css          # Main styles
β”‚   β”‚   └── admin.css          # Admin styles
β”‚   β”œβ”€β”€ js/
β”‚   β”‚   β”œβ”€β”€ main.js            # Main JavaScript
β”‚   β”‚   β”œβ”€β”€ validation.js      # Form validation
β”‚   β”‚   └── charts.js          # Analytics charts
β”‚   └── images/
β”‚       └── logo.png           # Institute logo
β”‚
β”œβ”€β”€ uploads/                    # Uploaded files
β”‚   β”œβ”€β”€ results/                # Result PDFs
β”‚   └── imports/                # CSV import files
β”‚
β”œβ”€β”€ vendor/                     # Third-party libraries
β”‚   β”œβ”€β”€ fpdf/                   # PDF generator
β”‚   └── phpmailer/              # Email library
β”‚
└── database/
└── exam_result_system.sql  # Database dump

πŸ—„οΈ Database Setup (database/exam_result_system.sql)

Create a database named exam_result_db and run this SQL.

-- phpMyAdmin SQL Dump
-- Database: `exam_result_db`
CREATE DATABASE IF NOT EXISTS `exam_result_db`;
USE `exam_result_db`;
-- --------------------------------------------------------
-- Table structure for table `admins`
-- --------------------------------------------------------
CREATE TABLE `admins` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(100) NOT NULL,
`full_name` varchar(100) NOT NULL,
`role` enum('super_admin','admin') DEFAULT 'admin',
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Default admin (password: admin123)
INSERT INTO `admins` (`username`, `password`, `email`, `full_name`, `role`) VALUES
('admin', '$2y$10$YourHashedPasswordHere', '[email protected]', 'Administrator', 'super_admin');
-- --------------------------------------------------------
-- Table structure for table `students`
-- --------------------------------------------------------
CREATE TABLE `students` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`roll_number` varchar(50) NOT NULL,
`registration_number` varchar(50) DEFAULT NULL,
`full_name` varchar(100) NOT NULL,
`father_name` varchar(100) DEFAULT NULL,
`mother_name` varchar(100) DEFAULT NULL,
`date_of_birth` date NOT NULL,
`gender` enum('male','female','other') DEFAULT NULL,
`email` varchar(100) DEFAULT NULL,
`phone` varchar(20) DEFAULT NULL,
`address` text DEFAULT NULL,
`course` varchar(100) DEFAULT NULL,
`batch` varchar(50) DEFAULT NULL,
`semester` int(11) DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `roll_number` (`roll_number`),
UNIQUE KEY `registration_number` (`registration_number`),
KEY `email` (`email`),
KEY `date_of_birth` (`date_of_birth`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Sample students
INSERT INTO `students` (`roll_number`, `full_name`, `father_name`, `date_of_birth`, `email`, `phone`, `course`, `batch`, `semester`) VALUES
('2024001', 'John Doe', 'Robert Doe', '2002-05-15', '[email protected]', '9876543210', 'B.Tech Computer Science', '2024', 4),
('2024002', 'Jane Smith', 'Michael Smith', '2003-08-22', '[email protected]', '9876543211', 'B.Tech Computer Science', '2024', 4),
('2024003', 'Alice Johnson', 'David Johnson', '2002-11-30', '[email protected]', '9876543212', 'B.Tech Electronics', '2024', 4);
-- --------------------------------------------------------
-- Table structure for table `exams`
-- --------------------------------------------------------
CREATE TABLE `exams` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`exam_name` varchar(200) NOT NULL,
`exam_type` enum('internal','external','semester','final') DEFAULT 'semester',
`course` varchar(100) DEFAULT NULL,
`batch` varchar(50) DEFAULT NULL,
`semester` int(11) DEFAULT NULL,
`exam_date` date DEFAULT NULL,
`result_date` date DEFAULT NULL,
`max_marks` int(11) DEFAULT 100,
`passing_marks` int(11) DEFAULT 35,
`status` enum('draft','published','archived') DEFAULT 'draft',
`created_by` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `created_by` (`created_by`),
CONSTRAINT `exams_ibfk_1` FOREIGN KEY (`created_by`) REFERENCES `admins` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Sample exams
INSERT INTO `exams` (`exam_name`, `exam_type`, `course`, `batch`, `semester`, `exam_date`, `result_date`, `status`, `created_by`) VALUES
('B.Tech Semester 4 Final Examination 2024', 'semester', 'B.Tech Computer Science', '2024', 4, '2024-05-15', '2024-06-01', 'published', 1),
('B.Tech Semester 4 Internal Assessment', 'internal', 'B.Tech Computer Science', '2024', 4, '2024-03-10', '2024-03-20', 'published', 1);
-- --------------------------------------------------------
-- Table structure for table `subjects`
-- --------------------------------------------------------
CREATE TABLE `subjects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`subject_code` varchar(20) NOT NULL,
`subject_name` varchar(100) NOT NULL,
`course` varchar(100) DEFAULT NULL,
`semester` int(11) DEFAULT NULL,
`max_marks` int(11) DEFAULT 100,
`passing_marks` int(11) DEFAULT 35,
PRIMARY KEY (`id`),
UNIQUE KEY `subject_code` (`subject_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Sample subjects
INSERT INTO `subjects` (`subject_code`, `subject_name`, `course`, `semester`, `max_marks`, `passing_marks`) VALUES
('CS401', 'Database Management Systems', 'B.Tech Computer Science', 4, 100, 35),
('CS402', 'Operating Systems', 'B.Tech Computer Science', 4, 100, 35),
('CS403', 'Computer Networks', 'B.Tech Computer Science', 4, 100, 35),
('CS404', 'Software Engineering', 'B.Tech Computer Science', 4, 100, 35),
('CS405', 'Web Technologies', 'B.Tech Computer Science', 4, 100, 35);
-- --------------------------------------------------------
-- Table structure for table `results`
-- --------------------------------------------------------
CREATE TABLE `results` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`exam_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
`subject_id` int(11) NOT NULL,
`marks_obtained` decimal(5,2) NOT NULL,
`max_marks` int(11) DEFAULT 100,
`grade` varchar(2) DEFAULT NULL,
`grade_point` decimal(3,2) DEFAULT NULL,
`remarks` varchar(255) DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `unique_result` (`exam_id`,`student_id`,`subject_id`),
KEY `exam_id` (`exam_id`),
KEY `student_id` (`student_id`),
KEY `subject_id` (`subject_id`),
CONSTRAINT `results_ibfk_1` FOREIGN KEY (`exam_id`) REFERENCES `exams` (`id`) ON DELETE CASCADE,
CONSTRAINT `results_ibfk_2` FOREIGN KEY (`student_id`) REFERENCES `students` (`id`) ON DELETE CASCADE,
CONSTRAINT `results_ibfk_3` FOREIGN KEY (`subject_id`) REFERENCES `subjects` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Sample results for student 1 (John Doe)
INSERT INTO `results` (`exam_id`, `student_id`, `subject_id`, `marks_obtained`, `grade`, `grade_point`) VALUES
(1, 1, 1, 85.50, 'A', 9.0),
(1, 1, 2, 78.00, 'B+', 8.0),
(1, 1, 3, 92.00, 'A+', 10.0),
(1, 1, 4, 88.50, 'A', 9.0),
(1, 1, 5, 76.00, 'B+', 8.0);
-- Sample results for student 2 (Jane Smith)
INSERT INTO `results` (`exam_id`, `student_id`, `subject_id`, `marks_obtained`, `grade`, `grade_point`) VALUES
(1, 2, 1, 91.00, 'A+', 10.0),
(1, 2, 2, 88.00, 'A', 9.0),
(1, 2, 3, 79.00, 'B+', 8.0),
(1, 2, 4, 94.00, 'A+', 10.0),
(1, 2, 5, 87.00, 'A', 9.0);
-- --------------------------------------------------------
-- Table structure for table `overall_results`
-- --------------------------------------------------------
CREATE TABLE `overall_results` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`exam_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
`total_marks` decimal(7,2) NOT NULL,
`percentage` decimal(5,2) NOT NULL,
`grade` varchar(2) DEFAULT NULL,
`cgpa` decimal(3,2) DEFAULT NULL,
`rank` int(11) DEFAULT NULL,
`status` enum('pass','fail','compartment') DEFAULT 'pass',
`published_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_overall` (`exam_id`,`student_id`),
KEY `exam_id` (`exam_id`),
KEY `student_id` (`student_id`),
CONSTRAINT `overall_results_ibfk_1` FOREIGN KEY (`exam_id`) REFERENCES `exams` (`id`) ON DELETE CASCADE,
CONSTRAINT `overall_results_ibfk_2` FOREIGN KEY (`student_id`) REFERENCES `students` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Sample overall results
INSERT INTO `overall_results` (`exam_id`, `student_id`, `total_marks`, `percentage`, `grade`, `cgpa`, `rank`, `status`) VALUES
(1, 1, 420.00, 84.00, 'A', 8.8, 2, 'pass'),
(1, 2, 439.00, 87.80, 'A+', 9.2, 1, 'pass');
-- --------------------------------------------------------
-- Table structure for table `notifications`
-- --------------------------------------------------------
CREATE TABLE `notifications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) DEFAULT NULL,
`exam_id` int(11) DEFAULT NULL,
`type` varchar(50) NOT NULL,
`subject` varchar(200) NOT NULL,
`message` text NOT NULL,
`sent_via` enum('email','sms','both') DEFAULT 'email',
`sent_at` timestamp NULL DEFAULT NULL,
`status` enum('pending','sent','failed') DEFAULT 'pending',
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (`id`),
KEY `student_id` (`student_id`),
KEY `exam_id` (`exam_id`),
CONSTRAINT `notifications_ibfk_1` FOREIGN KEY (`student_id`) REFERENCES `students` (`id`) ON DELETE CASCADE,
CONSTRAINT `notifications_ibfk_2` FOREIGN KEY (`exam_id`) REFERENCES `exams` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
COMMIT;

πŸ’» Core PHP Files

1. Database Configuration (includes/config.php)

<?php
// Database configuration
define('DB_HOST', 'localhost');
define('DB_NAME', 'exam_result_db');
define('DB_USER', 'root');
define('DB_PASS', '');
try {
$pdo = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8mb4",
DB_USER,
DB_PASS,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
]
);
} catch (PDOException $e) {
die("Connection failed: " . $e->getMessage());
}
// Start session if not started
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
// Site configuration
define('SITE_NAME', 'Online Exam Result System');
define('INSTITUTE_NAME', 'Institute Name');
define('SITE_URL', 'http://localhost/online-exam-result/');
define('ADMIN_EMAIL', '[email protected]');
// Helper functions
function sanitize($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
function redirect($url) {
header("Location: $url");
exit;
}
function isAdminLoggedIn() {
return isset($_SESSION['admin_id']);
}
function formatDate($date, $format = 'd M Y') {
return date($format, strtotime($date));
}
function calculatePercentage($obtained, $total) {
if ($total == 0) return 0;
return round(($obtained / $total) * 100, 2);
}
function calculateGrade($percentage) {
if ($percentage >= 90) return ['grade' => 'A+', 'grade_point' => 10.0];
if ($percentage >= 80) return ['grade' => 'A', 'grade_point' => 9.0];
if ($percentage >= 70) return ['grade' => 'B+', 'grade_point' => 8.0];
if ($percentage >= 60) return ['grade' => 'B', 'grade_point' => 7.0];
if ($percentage >= 50) return ['grade' => 'C+', 'grade_point' => 6.0];
if ($percentage >= 40) return ['grade' => 'C', 'grade_point' => 5.0];
if ($percentage >= 35) return ['grade' => 'D', 'grade_point' => 4.0];
return ['grade' => 'F', 'grade_point' => 0.0];
}
function getResultStatus($results) {
$failed = false;
foreach ($results as $result) {
if ($result['marks_obtained'] < $result['passing_marks']) {
$failed = true;
break;
}
}
return $failed ? 'fail' : 'pass';
}
function sendEmail($to, $subject, $message) {
// Use PHPMailer for production
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= "From: " . SITE_NAME . " <noreply@" . $_SERVER['HTTP_HOST'] . ">\r\n";
return mail($to, $subject, $message, $headers);
}
?>

2. Admin Authentication (includes/auth.php)

<?php
require_once 'config.php';
class Auth {
public static function login($username, $password) {
global $pdo;
$stmt = $pdo->prepare("SELECT * FROM admins WHERE username = ? OR email = ?");
$stmt->execute([$username, $username]);
$admin = $stmt->fetch();
if ($admin && password_verify($password, $admin['password'])) {
$_SESSION['admin_id'] = $admin['id'];
$_SESSION['admin_name'] = $admin['full_name'];
$_SESSION['admin_username'] = $admin['username'];
$_SESSION['admin_role'] = $admin['role'];
return true;
}
return false;
}
public static function logout() {
session_destroy();
redirect('login.php');
}
public static function checkLogin() {
if (!isset($_SESSION['admin_id'])) {
redirect('login.php');
}
}
public static function checkSuperAdmin() {
self::checkLogin();
if ($_SESSION['admin_role'] !== 'super_admin') {
$_SESSION['error'] = 'You do not have permission to access this page';
redirect('dashboard.php');
}
}
public static function getCurrentAdmin() {
global $pdo;
if (!isset($_SESSION['admin_id'])) {
return null;
}
$stmt = $pdo->prepare("SELECT * FROM admins WHERE id = ?");
$stmt->execute([$_SESSION['admin_id']]);
return $stmt->fetch();
}
}
?>

3. Homepage - Result Search (index.php)

<?php
require_once 'includes/config.php';
$error = '';
$recent_exams = $pdo->query("
SELECT * FROM exams 
WHERE status = 'published' 
ORDER BY result_date DESC 
LIMIT 5
")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<!-- Header -->
<header class="site-header">
<div class="container">
<div class="logo">
<h1><?php echo INSTITUTE_NAME; ?></h1>
<p><?php echo SITE_NAME; ?></p>
</div>
<nav>
<ul>
<li><a href="index.php" class="active">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
<li><a href="login.php" class="btn-admin">Admin Login</a></li>
</ul>
</nav>
</div>
</header>
<!-- Hero Section with Search -->
<section class="hero">
<div class="container">
<h2>Check Your Exam Result</h2>
<p>Enter your roll number and date of birth to view your result</p>
<?php if ($error): ?>
<div class="alert alert-error"><?php echo $error; ?></div>
<?php endif; ?>
<form action="result.php" method="GET" class="search-form" id="result-search-form">
<div class="form-group">
<label for="roll_number">Roll Number</label>
<input type="text" id="roll_number" name="roll_number" 
placeholder="Enter your roll number" required>
</div>
<div class="form-group">
<label for="dob">Date of Birth</label>
<input type="date" id="dob" name="dob" required>
</div>
<div class="form-group">
<label for="exam">Select Exam (Optional)</label>
<select id="exam" name="exam_id">
<option value="">Latest Exam</option>
<?php foreach ($recent_exams as $exam): ?>
<option value="<?php echo $exam['id']; ?>">
<?php echo $exam['exam_name']; ?> (<?php echo formatDate($exam['result_date']); ?>)
</option>
<?php endforeach; ?>
</select>
</div>
<button type="submit" class="btn btn-large">View Result</button>
</form>
</div>
</section>
<!-- Features Section -->
<section class="features">
<div class="container">
<h2>Features</h2>
<div class="feature-grid">
<div class="feature-card">
<div class="feature-icon">πŸ”</div>
<h3>Easy Access</h3>
<p>View your results anytime, anywhere with just your roll number and date of birth.</p>
</div>
<div class="feature-card">
<div class="feature-icon">πŸ“Š</div>
<h3>Detailed Results</h3>
<p>Get subject-wise marks, percentage, grade, and overall performance analysis.</p>
</div>
<div class="feature-card">
<div class="feature-icon">πŸ“₯</div>
<h3>Download PDF</h3>
<p>Download and print your result for future reference or official purposes.</p>
</div>
<div class="feature-card">
<div class="feature-icon">πŸ“±</div>
<h3>Mobile Friendly</h3>
<p>Access results on any device - desktop, tablet, or mobile phone.</p>
</div>
</div>
</div>
</section>
<!-- Recent Results Section -->
<section class="recent-results">
<div class="container">
<h2>Recently Published Results</h2>
<div class="exam-list">
<?php foreach ($recent_exams as $exam): ?>
<div class="exam-item">
<div class="exam-info">
<h3><?php echo $exam['exam_name']; ?></h3>
<p>Published on: <?php echo formatDate($exam['result_date']); ?></p>
</div>
<a href="?exam_id=<?php echo $exam['id']; ?>" class="btn">Check Result</a>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<!-- Footer -->
<footer>
<div class="container">
<p>&copy; 2024 <?php echo INSTITUTE_NAME; ?>. All rights reserved.</p>
</div>
</footer>
<script src="assets/js/main.js"></script>
</body>
</html>

4. Display Result Page (result.php)

<?php
require_once 'includes/config.php';
$roll_number = $_GET['roll_number'] ?? '';
$dob = $_GET['dob'] ?? '';
$exam_id = isset($_GET['exam_id']) ? (int)$_GET['exam_id'] : 0;
if (empty($roll_number) || empty($dob)) {
$_SESSION['error'] = 'Please provide roll number and date of birth';
redirect('index.php');
}
// Get student details
$stmt = $pdo->prepare("SELECT * FROM students WHERE roll_number = ? AND date_of_birth = ?");
$stmt->execute([$roll_number, $dob]);
$student = $stmt->fetch();
if (!$student) {
$_SESSION['error'] = 'Invalid roll number or date of birth';
redirect('index.php');
}
// Get exams available for this student
$exam_query = "
SELECT DISTINCT e.* 
FROM exams e
JOIN overall_results o ON e.id = o.exam_id
WHERE o.student_id = ? AND e.status = 'published'
";
if ($exam_id > 0) {
$exam_query .= " AND e.id = ?";
$stmt = $pdo->prepare($exam_query);
$stmt->execute([$student['id'], $exam_id]);
} else {
$stmt = $pdo->prepare($exam_query . " ORDER BY e.result_date DESC LIMIT 1");
$stmt->execute([$student['id']]);
}
$exam = $stmt->fetch();
if (!$exam) {
$_SESSION['error'] = 'No result found for this student';
redirect('index.php');
}
// Get overall result
$stmt = $pdo->prepare("
SELECT * FROM overall_results 
WHERE exam_id = ? AND student_id = ?
");
$stmt->execute([$exam['id'], $student['id']]);
$overall = $stmt->fetch();
// Get subject-wise results
$stmt = $pdo->prepare("
SELECT r.*, s.subject_code, s.subject_name, s.max_marks as subject_max_marks, 
s.passing_marks as subject_passing_marks
FROM results r
JOIN subjects s ON r.subject_id = s.id
WHERE r.exam_id = ? AND r.student_id = ?
ORDER BY s.subject_code
");
$stmt->execute([$exam['id'], $student['id']]);
$subject_results = $stmt->fetchAll();
// Calculate total and percentage
$total_obtained = 0;
$total_max = 0;
foreach ($subject_results as $result) {
$total_obtained += $result['marks_obtained'];
$total_max += $result['max_marks'];
}
$percentage = calculatePercentage($total_obtained, $total_max);
$grade_info = calculateGrade($percentage);
$status = getResultStatus($subject_results);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Exam Result - <?php echo $student['full_name']; ?></title>
<link rel="stylesheet" href="assets/css/style.css">
</head>
<body>
<!-- Header -->
<header class="site-header">
<div class="container">
<div class="logo">
<h1><?php echo INSTITUTE_NAME; ?></h1>
<p><?php echo SITE_NAME; ?></p>
</div>
<nav>
<ul>
<li><a href="index.php">Home</a></li>
<li><a href="login.php" class="btn-admin">Admin Login</a></li>
</ul>
</nav>
</div>
</header>
<!-- Result Container -->
<div class="container">
<div class="result-container">
<div class="result-header">
<h2>Examination Result</h2>
<h3><?php echo $exam['exam_name']; ?></h3>
<p>Published on: <?php echo formatDate($exam['result_date']); ?></p>
</div>
<!-- Student Information -->
<div class="student-info">
<table class="info-table">
<tr>
<th>Student Name:</th>
<td><?php echo $student['full_name']; ?></td>
<th>Roll Number:</th>
<td><?php echo $student['roll_number']; ?></td>
</tr>
<tr>
<th>Father's Name:</th>
<td><?php echo $student['father_name']; ?></td>
<th>Course:</th>
<td><?php echo $student['course']; ?></td>
</tr>
<tr>
<th>Date of Birth:</th>
<td><?php echo formatDate($student['date_of_birth']); ?></td>
<th>Semester:</th>
<td><?php echo $student['semester']; ?></td>
</tr>
</table>
</div>
<!-- Subject-wise Marks -->
<div class="marks-table">
<h3>Subject-wise Marks</h3>
<table>
<thead>
<tr>
<th>Subject Code</th>
<th>Subject Name</th>
<th>Max Marks</th>
<th>Marks Obtained</th>
<th>Grade</th>
<th>Grade Point</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($subject_results as $result): 
$passed = $result['marks_obtained'] >= $result['subject_passing_marks'];
?>
<tr>
<td><?php echo $result['subject_code']; ?></td>
<td><?php echo $result['subject_name']; ?></td>
<td><?php echo $result['max_marks']; ?></td>
<td><?php echo number_format($result['marks_obtained'], 2); ?></td>
<td><?php echo $result['grade']; ?></td>
<td><?php echo $result['grade_point']; ?></td>
<td>
<span class="badge <?php echo $passed ? 'badge-success' : 'badge-danger'; ?>">
<?php echo $passed ? 'Pass' : 'Fail'; ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot>
<tr>
<th colspan="3">Total</th>
<th><?php echo number_format($total_obtained, 2); ?> / <?php echo $total_max; ?></th>
<th colspan="3"></th>
</tr>
</tfoot>
</table>
</div>
<!-- Overall Result -->
<div class="overall-result">
<h3>Overall Performance</h3>
<div class="result-summary">
<div class="summary-item">
<label>Percentage:</label>
<span class="value"><?php echo number_format($percentage, 2); ?>%</span>
</div>
<div class="summary-item">
<label>Grade:</label>
<span class="value"><?php echo $grade_info['grade']; ?></span>
</div>
<div class="summary-item">
<label>CGPA:</label>
<span class="value"><?php echo number_format($grade_info['grade_point'], 2); ?></span>
</div>
<div class="summary-item">
<label>Rank:</label>
<span class="value"><?php echo $overall['rank'] ?? 'N/A'; ?></span>
</div>
<div class="summary-item">
<label>Status:</label>
<span class="value badge <?php echo $status == 'pass' ? 'badge-success' : 'badge-danger'; ?>">
<?php echo strtoupper($status); ?>
</span>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="result-actions">
<a href="download-result.php?student=<?php echo $student['id']; ?>&exam=<?php echo $exam['id']; ?>" 
class="btn btn-primary">
πŸ“₯ Download PDF
</a>
<a href="index.php" class="btn">
πŸ” Check Another Result
</a>
</div>
<!-- Disclaimer -->
<div class="disclaimer">
<p><strong>Note:</strong> This is a computer-generated result. No signature is required.</p>
<p>For any discrepancies, please contact the examination department.</p>
</div>
</div>
</div>
<!-- Footer -->
<footer>
<div class="container">
<p>&copy; 2024 <?php echo INSTITUTE_NAME; ?>. All rights reserved.</p>
</div>
</footer>
</body>
</html>

5. Admin Login Page (admin/login.php)

<?php
require_once '../includes/config.php';
require_once '../includes/auth.php';
// If already logged in, redirect to dashboard
if (isAdminLoggedIn()) {
redirect('dashboard.php');
}
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
if (Auth::login($username, $password)) {
redirect('dashboard.php');
} else {
$error = 'Invalid username or password';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Login - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="../assets/css/admin.css">
</head>
<body class="login-page">
<div class="login-container">
<div class="login-header">
<h1><?php echo SITE_NAME; ?></h1>
<p>Admin Panel Login</p>
</div>
<?php if ($error): ?>
<div class="alert alert-error"><?php echo $error; ?></div>
<?php endif; ?>
<form method="POST" action="" class="login-form">
<div class="form-group">
<label for="username">Username or Email</label>
<input type="text" id="username" name="username" required 
placeholder="Enter your username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" name="password" required 
placeholder="Enter your password">
</div>
<button type="submit" class="btn btn-primary btn-block">Login</button>
</form>
<div class="login-footer">
<a href="../index.php">← Back to Website</a>
</div>
</div>
</body>
</html>

6. Admin Dashboard (admin/dashboard.php)

<?php
require_once '../includes/config.php';
require_once '../includes/auth.php';
Auth::checkLogin();
// Get statistics
$totalStudents = $pdo->query("SELECT COUNT(*) FROM students")->fetchColumn();
$totalExams = $pdo->query("SELECT COUNT(*) FROM exams")->fetchColumn();
$publishedExams = $pdo->query("SELECT COUNT(*) FROM exams WHERE status = 'published'")->fetchColumn();
$totalResults = $pdo->query("SELECT COUNT(DISTINCT student_id) FROM overall_results")->fetchColumn();
// Recent exams
$recentExams = $pdo->query("
SELECT e.*, 
(SELECT COUNT(DISTINCT student_id) FROM overall_results WHERE exam_id = e.id) as student_count
FROM exams e
ORDER BY e.created_at DESC
LIMIT 5
")->fetchAll();
// Recent students
$recentStudents = $pdo->query("
SELECT * FROM students 
ORDER BY created_at DESC 
LIMIT 5
")->fetchAll();
// Toppers
$toppers = $pdo->prepare("
SELECT s.full_name, s.roll_number, o.percentage, o.rank, e.exam_name
FROM overall_results o
JOIN students s ON o.student_id = s.id
JOIN exams e ON o.exam_id = e.id
WHERE o.rank = 1 AND e.status = 'published'
ORDER BY o.exam_id DESC
LIMIT 5
");
$toppers->execute();
$toppersList = $toppers->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Dashboard - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="../assets/css/admin.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div class="admin-wrapper">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<h2>Exam Result Admin</h2>
<p>Welcome, <?php echo $_SESSION['admin_name']; ?></p>
</div>
<nav class="sidebar-nav">
<ul>
<li><a href="dashboard.php" class="active">Dashboard</a></li>
<li><a href="exams.php">Manage Exams</a></li>
<li><a href="results.php">Manage Results</a></li>
<li><a href="students.php">Manage Students</a></li>
<li><a href="import-results.php">Import Results</a></li>
<li><a href="reports.php">Reports</a></li>
<li><a href="merit-list.php">Merit List</a></li>
<li><a href="settings.php">Settings</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="admin-main">
<div class="container">
<h1>Dashboard</h1>
<!-- Stats Cards -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon">πŸ‘₯</div>
<div class="stat-details">
<h3><?php echo $totalStudents; ?></h3>
<p>Total Students</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">πŸ“</div>
<div class="stat-details">
<h3><?php echo $totalExams; ?></h3>
<p>Total Exams</p>
<small><?php echo $publishedExams; ?> published</small>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">πŸ“Š</div>
<div class="stat-details">
<h3><?php echo $totalResults; ?></h3>
<p>Results Published</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon">πŸ†</div>
<div class="stat-details">
<h3><?php echo count($toppersList); ?></h3>
<p>Toppers</p>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="quick-actions">
<a href="add-exam.php" class="action-card">
<span class="action-icon">βž•</span>
<span>Add New Exam</span>
</a>
<a href="add-result.php" class="action-card">
<span class="action-icon">πŸ“₯</span>
<span>Add Result</span>
</a>
<a href="import-results.php" class="action-card">
<span class="action-icon">πŸ“€</span>
<span>Import Results</span>
</a>
<a href="add-student.php" class="action-card">
<span class="action-icon">πŸ‘€</span>
<span>Add Student</span>
</a>
</div>
<div class="dashboard-grid">
<!-- Recent Exams -->
<div class="card">
<div class="card-header">
<h3>Recent Exams</h3>
<a href="exams.php" class="btn btn-sm">View All</a>
</div>
<div class="card-body">
<table class="data-table">
<thead>
<tr>
<th>Exam Name</th>
<th>Result Date</th>
<th>Students</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($recentExams as $exam): ?>
<tr>
<td><?php echo $exam['exam_name']; ?></td>
<td><?php echo formatDate($exam['result_date']); ?></td>
<td><?php echo $exam['student_count']; ?></td>
<td>
<span class="badge badge-<?php echo $exam['status']; ?>">
<?php echo $exam['status']; ?>
</span>
</td>
<td>
<a href="edit-exam.php?id=<?php echo $exam['id']; ?>" class="btn-small">Edit</a>
<a href="results.php?exam=<?php echo $exam['id']; ?>" class="btn-small">Results</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Recent Students -->
<div class="card">
<div class="card-header">
<h3>Recent Students</h3>
<a href="students.php" class="btn btn-sm">View All</a>
</div>
<div class="card-body">
<table class="data-table">
<thead>
<tr>
<th>Roll No</th>
<th>Name</th>
<th>Course</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($recentStudents as $student): ?>
<tr>
<td><?php echo $student['roll_number']; ?></td>
<td><?php echo $student['full_name']; ?></td>
<td><?php echo $student['course']; ?></td>
<td>
<a href="edit-student.php?id=<?php echo $student['id']; ?>" class="btn-small">Edit</a>
<a href="results.php?student=<?php echo $student['id']; ?>" class="btn-small">Results</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Recent Toppers -->
<div class="card">
<div class="card-header">
<h3>Recent Toppers</h3>
</div>
<div class="card-body">
<table class="data-table">
<thead>
<tr>
<th>Name</th>
<th>Exam</th>
<th>Percentage</th>
<th>Rank</th>
</tr>
</thead>
<tbody>
<?php foreach ($toppersList as $topper): ?>
<tr>
<td><?php echo $topper['full_name']; ?></td>
<td><?php echo $topper['exam_name']; ?></td>
<td><?php echo $topper['percentage']; ?>%</td>
<td><span class="badge badge-success">#<?php echo $topper['rank']; ?></span></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
</div>
<script src="../assets/js/admin.js"></script>
</body>
</html>

7. Admin - Manage Exams (admin/exams.php)

<?php
require_once '../includes/config.php';
require_once '../includes/auth.php';
Auth::checkLogin();
// Handle exam deletion
if (isset($_GET['delete'])) {
$id = (int)$_GET['delete'];
// Check if exam has results
$check = $pdo->prepare("SELECT COUNT(*) FROM overall_results WHERE exam_id = ?");
$check->execute([$id]);
$count = $check->fetchColumn();
if ($count > 0) {
$_SESSION['error'] = 'Cannot delete exam with existing results';
} else {
$pdo->prepare("DELETE FROM exams WHERE id = ?")->execute([$id]);
$_SESSION['success'] = 'Exam deleted successfully';
}
redirect('exams.php');
}
// Get all exams
$exams = $pdo->query("
SELECT e.*, 
(SELECT COUNT(DISTINCT student_id) FROM overall_results WHERE exam_id = e.id) as student_count,
a.full_name as created_by_name
FROM exams e
LEFT JOIN admins a ON e.created_by = a.id
ORDER BY e.created_at DESC
")->fetchAll();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Manage Exams - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="../assets/css/admin.css">
</head>
<body>
<div class="admin-wrapper">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<h2>Exam Result Admin</h2>
<p>Welcome, <?php echo $_SESSION['admin_name']; ?></p>
</div>
<nav class="sidebar-nav">
<ul>
<li><a href="dashboard.php">Dashboard</a></li>
<li><a href="exams.php" class="active">Manage Exams</a></li>
<li><a href="results.php">Manage Results</a></li>
<li><a href="students.php">Manage Students</a></li>
<li><a href="import-results.php">Import Results</a></li>
<li><a href="reports.php">Reports</a></li>
<li><a href="merit-list.php">Merit List</a></li>
<li><a href="settings.php">Settings</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="admin-main">
<div class="container">
<div class="page-header">
<h1>Manage Exams</h1>
<a href="add-exam.php" class="btn btn-primary">+ Add New Exam</a>
</div>
<?php if (isset($_SESSION['success'])): ?>
<div class="alert alert-success"><?php echo $_SESSION['success']; unset($_SESSION['success']); ?></div>
<?php endif; ?>
<?php if (isset($_SESSION['error'])): ?>
<div class="alert alert-error"><?php echo $_SESSION['error']; unset($_SESSION['error']); ?></div>
<?php endif; ?>
<div class="card">
<div class="card-body">
<table class="data-table">
<thead>
<tr>
<th>ID</th>
<th>Exam Name</th>
<th>Type</th>
<th>Course</th>
<th>Semester</th>
<th>Exam Date</th>
<th>Result Date</th>
<th>Students</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($exams as $exam): ?>
<tr>
<td>#<?php echo $exam['id']; ?></td>
<td><?php echo $exam['exam_name']; ?></td>
<td><?php echo ucfirst($exam['exam_type']); ?></td>
<td><?php echo $exam['course']; ?></td>
<td><?php echo $exam['semester']; ?></td>
<td><?php echo formatDate($exam['exam_date']); ?></td>
<td><?php echo formatDate($exam['result_date']); ?></td>
<td><?php echo $exam['student_count']; ?></td>
<td>
<span class="badge badge-<?php echo $exam['status']; ?>">
<?php echo $exam['status']; ?>
</span>
</td>
<td class="actions">
<a href="edit-exam.php?id=<?php echo $exam['id']; ?>" class="btn-small">Edit</a>
<a href="results.php?exam=<?php echo $exam['id']; ?>" class="btn-small">Results</a>
<a href="?delete=<?php echo $exam['id']; ?>" 
class="btn-small btn-danger"
onclick="return confirm('Are you sure you want to delete this exam?')">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</main>
</div>
</body>
</html>

8. Admin - Add Exam (admin/add-exam.php)

<?php
require_once '../includes/config.php';
require_once '../includes/auth.php';
Auth::checkLogin();
$errors = [];
$form_data = [
'exam_name' => '',
'exam_type' => 'semester',
'course' => '',
'batch' => '',
'semester' => '',
'exam_date' => '',
'result_date' => '',
'max_marks' => 100,
'passing_marks' => 35,
'status' => 'draft'
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Sanitize input
$form_data['exam_name'] = sanitize($_POST['exam_name']);
$form_data['exam_type'] = $_POST['exam_type'];
$form_data['course'] = sanitize($_POST['course']);
$form_data['batch'] = sanitize($_POST['batch']);
$form_data['semester'] = (int)$_POST['semester'];
$form_data['exam_date'] = $_POST['exam_date'];
$form_data['result_date'] = $_POST['result_date'];
$form_data['max_marks'] = (int)$_POST['max_marks'];
$form_data['passing_marks'] = (int)$_POST['passing_marks'];
$form_data['status'] = $_POST['status'];
// Validate
if (empty($form_data['exam_name'])) {
$errors['exam_name'] = 'Exam name is required';
}
if (empty($form_data['course'])) {
$errors['course'] = 'Course is required';
}
if (empty($form_data['exam_date'])) {
$errors['exam_date'] = 'Exam date is required';
}
if (empty($form_data['result_date'])) {
$errors['result_date'] = 'Result date is required';
}
if ($form_data['passing_marks'] > $form_data['max_marks']) {
$errors['passing_marks'] = 'Passing marks cannot exceed maximum marks';
}
if (empty($errors)) {
// Insert exam
$stmt = $pdo->prepare("
INSERT INTO exams (exam_name, exam_type, course, batch, semester, exam_date, result_date, 
max_marks, passing_marks, status, created_by)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
");
$success = $stmt->execute([
$form_data['exam_name'],
$form_data['exam_type'],
$form_data['course'],
$form_data['batch'],
$form_data['semester'],
$form_data['exam_date'],
$form_data['result_date'],
$form_data['max_marks'],
$form_data['passing_marks'],
$form_data['status'],
$_SESSION['admin_id']
]);
if ($success) {
$_SESSION['success'] = 'Exam created successfully';
redirect('exams.php');
} else {
$errors['general'] = 'Failed to create exam. Please try again.';
}
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Exam - <?php echo SITE_NAME; ?></title>
<link rel="stylesheet" href="../assets/css/admin.css">
</head>
<body>
<div class="admin-wrapper">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-header">
<h2>Exam Result Admin</h2>
<p>Welcome, <?php echo $_SESSION['admin_name']; ?></p>
</div>
<nav class="sidebar-nav">
<ul>
<li><a href="dashboard.php">Dashboard</a></li>
<li><a href="exams.php" class="active">Manage Exams</a></li>
<li><a href="results.php">Manage Results</a></li>
<li><a href="students.php">Manage Students</a></li>
<li><a href="import-results.php">Import Results</a></li>
<li><a href="reports.php">Reports</a></li>
<li><a href="merit-list.php">Merit List</a></li>
<li><a href="settings.php">Settings</a></li>
<li><a href="logout.php">Logout</a></li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="admin-main">
<div class="container">
<div class="page-header">
<h1>Add New Exam</h1>
<a href="exams.php" class="btn">← Back to Exams</a>
</div>
<?php if (!empty($errors['general'])): ?>
<div class="alert alert-error"><?php echo $errors['general']; ?></div>
<?php endif; ?>
<div class="card">
<div class="card-body">
<form method="POST" action="" class="admin-form">
<div class="form-row">
<div class="form-group col-md-8">
<label for="exam_name">Exam Name *</label>
<input type="text" id="exam_name" name="exam_name" 
value="<?php echo htmlspecialchars($form_data['exam_name']); ?>" required>
<?php if (isset($errors['exam_name'])): ?>
<span class="error"><?php echo $errors['exam_name']; ?></span>
<?php endif; ?>
</div>
<div class="form-group col-md-4">
<label for="exam_type">Exam Type</label>
<select id="exam_type" name="exam_type">
<option value="internal" <?php echo $form_data['exam_type'] == 'internal' ? 'selected' : ''; ?>>Internal</option>
<option value="external" <?php echo $form_data['exam_type'] == 'external' ? 'selected' : ''; ?>>External</option>
<option value="semester" <?php echo $form_data['exam_type'] == 'semester' ? 'selected' : ''; ?>>Semester</option>
<option value="final" <?php echo $form_data['exam_type'] == 'final' ? 'selected' : ''; ?>>Final</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<label for="course">Course *</label>
<input type="text" id="course" name="course" 
value="<?php echo htmlspecialchars($form_data['course']); ?>" 
placeholder="e.g., B.Tech Computer Science" required>
<?php if (isset($errors['course'])): ?>
<span class="error"><?php echo $errors['course']; ?></span>
<?php endif; ?>
</div>
<div class="form-group col-md-4">
<label for="batch">Batch</label>
<input type="text" id="batch" name="batch" 
value="<?php echo htmlspecialchars($form_data['batch']); ?>" 
placeholder="e.g., 2024">
</div>
<div class="form-group col-md-4">
<label for="semester">Semester</label>
<input type="number" id="semester" name="semester" 
value="<?php echo $form_data['semester']; ?>" min="1" max="8">
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="exam_date">Exam Date *</label>
<input type="date" id="exam_date" name="exam_date" 
value="<?php echo $form_data['exam_date']; ?>" required>
<?php if (isset($errors['exam_date'])): ?>
<span class="error"><?php echo $errors['exam_date']; ?></span>
<?php endif; ?>
</div>
<div class="form-group col-md-6">
<label for="result_date">Result Date *</label>
<input type="date" id="result_date" name="result_date" 
value="<?php echo $form_data['result_date']; ?>" required>
<?php if (isset($errors['result_date'])): ?>
<span class="error"><?php echo $errors['result_date']; ?></span>
<?php endif; ?>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="max_marks">Maximum Marks</label>
<input type="number" id="max_marks" name="max_marks" 
value="<?php echo $form_data['max_marks']; ?>" min="1" max="500">
</div>
<div class="form-group col-md-6">
<label for="passing_marks">Passing Marks</label>
<input type="number" id="passing_marks" name="passing_marks" 
value="<?php echo $form_data['passing_marks']; ?>" min="1" max="500">
<?php if (isset($errors['passing_marks'])): ?>
<span class="error"><?php echo $errors['passing_marks']; ?></span>
<?php endif; ?>
</div>
</div>
<div class="form-group">
<label for="status">Status</label>
<select id="status" name="status">
<option value="draft" <?php echo $form_data['status'] == 'draft' ? 'selected' : ''; ?>>Draft</option>
<option value="published" <?php echo $form_data['status'] == 'published' ? 'selected' : ''; ?>>Published</option>
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Create Exam</button>
<a href="exams.php" class="btn">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</main>
</div>
</body>
</html>

9. CSS Styling (assets/css/style.css)

/* Main Styles for Online Exam Result System */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
background: #f4f6f9;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
/* Header */
.site-header {
background: #2c3e50;
color: white;
padding: 1rem 0;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.site-header .container {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo h1 {
font-size: 1.5rem;
margin-bottom: 0.25rem;
}
.logo p {
font-size: 0.9rem;
opacity: 0.9;
}
nav ul {
list-style: none;
display: flex;
gap: 1.5rem;
}
nav a {
color: white;
text-decoration: none;
font-weight: 500;
transition: color 0.3s;
}
nav a:hover {
color: #3498db;
}
.btn-admin {
background: #3498db;
padding: 0.5rem 1rem;
border-radius: 4px;
}
.btn-admin:hover {
background: #2980b9;
color: white;
}
/* Hero Section */
.hero {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 4rem 0;
text-align: center;
}
.hero h2 {
font-size: 2.5rem;
margin-bottom: 1rem;
}
.hero p {
font-size: 1.2rem;
margin-bottom: 2rem;
opacity: 0.9;
}
/* Search Form */
.search-form {
max-width: 600px;
margin: 0 auto;
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
.form-group {
margin-bottom: 1.5rem;
text-align: left;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
color: #333;
font-weight: 500;
}
.form-group input,
.form-group select {
width: 100%;
padding: 0.75rem;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 1rem;
transition: border-color 0.3s;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #3498db;
}
.btn {
display: inline-block;
padding: 0.75rem 1.5rem;
background: #3498db;
color: white;
border: none;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
text-decoration: none;
transition: background 0.3s;
}
.btn:hover {
background: #2980b9;
}
.btn-large {
padding: 1rem 2rem;
font-size: 1.1rem;
}
/* Features Section */
.features {
padding: 4rem 0;
background: white;
}
.features h2 {
text-align: center;
margin-bottom: 3rem;
font-size: 2rem;
color: #2c3e50;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 2rem;
}
.feature-card {
text-align: center;
padding: 2rem;
border-radius: 8px;
background: #f8f9fa;
transition: transform 0.3s;
}
.feature-card:hover {
transform: translateY(-5px);
}
.feature-icon {
font-size: 3rem;
margin-bottom: 1rem;
}
.feature-card h3 {
margin-bottom: 1rem;
color: #2c3e50;
}
/* Recent Results Section */
.recent-results {
padding: 4rem 0;
background: #f4f6f9;
}
.recent-results h2 {
text-align: center;
margin-bottom: 3rem;
font-size: 2rem;
color: #2c3e50;
}
.exam-list {
max-width: 800px;
margin: 0 auto;
}
.exam-item {
background: white;
padding: 1.5rem;
margin-bottom: 1rem;
border-radius: 8px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.exam-info h3 {
margin-bottom: 0.5rem;
color: #2c3e50;
}
.exam-info p {
color: #666;
}
/* Result Page */
.result-container {
max-width: 1000px;
margin: 2rem auto;
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
}
.result-header {
text-align: center;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 2px solid #3498db;
}
.result-header h2 {
color: #2c3e50;
margin-bottom: 0.5rem;
}
.result-header h3 {
color: #666;
font-weight: normal;
margin-bottom: 0.5rem;
}
.student-info {
margin-bottom: 2rem;
background: #f8f9fa;
padding: 1.5rem;
border-radius: 8px;
}
.info-table {
width: 100%;
border-collapse: collapse;
}
.info-table th,
.info-table td {
padding: 0.75rem;
text-align: left;
border-bottom: 1px solid #dee2e6;
}
.info-table th {
width: 30%;
color: #666;
font-weight: 500;
}
.marks-table {
margin-bottom: 2rem;
}
.marks-table h3 {
margin-bottom: 1rem;
color: #2c3e50;
}
.marks-table table {
width: 100%;
border-collapse: collapse;
background: white;
}
.marks-table th,
.marks-table td {
padding: 1rem;
text-align: left;
border: 1px solid #dee2e6;
}
.marks-table th {
background: #3498db;
color: white;
}
.marks-table tfoot {
background: #f8f9fa;
font-weight: bold;
}
.overall-result {
background: #2c3e50;
color: white;
padding: 2rem;
border-radius: 8px;
margin-bottom: 2rem;
}
.overall-result h3 {
margin-bottom: 1rem;
color: #3498db;
}
.result-summary {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
}
.summary-item {
text-align: center;
}
.summary-item label {
display: block;
font-size: 0.9rem;
opacity: 0.9;
margin-bottom: 0.5rem;
}
.summary-item .value {
display: block;
font-size: 1.5rem;
font-weight: bold;
}
.result-actions {
display: flex;
gap: 1rem;
justify-content: center;
margin-bottom: 2rem;
}
.disclaimer {
font-size: 0.9rem;
color: #666;
text-align: center;
padding-top: 1rem;
border-top: 1px solid #dee2e6;
}
/* Badges */
.badge {
display: inline-block;
padding: 0.25rem 0.5rem;
border-radius: 3px;
font-size: 0.85rem;
font-weight: 500;
}
.badge-success {
background: #28a745;
color: white;
}
.badge-danger {
background: #dc3545;
color: white;
}
.badge-warning {
background: #ffc107;
color: #333;
}
/* Alerts */
.alert {
padding: 1rem;
border-radius: 4px;
margin-bottom: 1rem;
}
.alert-error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.alert-success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
/* Footer */
footer {
background: #2c3e50;
color: white;
text-align: center;
padding: 2rem 0;
margin-top: 2rem;
}
/* Responsive */
@media (max-width: 768px) {
.site-header .container {
flex-direction: column;
text-align: center;
gap: 1rem;
}
nav ul {
flex-wrap: wrap;
justify-content: center;
}
.hero h2 {
font-size: 2rem;
}
.feature-grid {
grid-template-columns: 1fr;
}
.exam-item {
flex-direction: column;
text-align: center;
gap: 1rem;
}
.info-table,
.info-table tbody,
.info-table tr,
.info-table th,
.info-table td {
display: block;
}
.info-table th {
width: 100%;
padding-bottom: 0;
}
.result-actions {
flex-direction: column;
}
.marks-table {
overflow-x: auto;
}
}

πŸ“ How to Use This Project (Step-by-Step Guide)

Step 1: Install Local Server

  1. Download and install XAMPP from apachefriends.org
  2. Launch XAMPP Control Panel
  3. Start Apache and MySQL services

Step 2: Create Project Folder

  1. Navigate to C:\xampp\htdocs\ (Windows) or /Applications/XAMPP/htdocs/ (Mac)
  2. Create a new folder named online-exam-result

Step 3: Set Up Database

  1. Open browser and go to http://localhost/phpmyadmin
  2. Click on "SQL" tab
  3. Copy the entire SQL from database/exam_result_system.sql
  4. Paste and click "Go" to create database and tables

Step 4: Create Password Hash

Create a file named hash.php in project root:

<?php
echo password_hash('admin123', PASSWORD_DEFAULT);
?>

Run it: http://localhost/online-exam-result/hash.php
Copy the hash and update it in the SQL insert statement for the admin user.

Step 5: Configure Database Connection

Open includes/config.php and verify:

define('DB_HOST', 'localhost');
define('DB_NAME', 'exam_result_db');
define('DB_USER', 'root');
define('DB_PASS', '');

Step 6: Test the Application

Student Side:

  • Open: http://localhost/online-exam-result/
  • Try searching with:
  • Roll Number: 2024001
  • Date of Birth: 2002-05-15

Admin Side:

  • Open: http://localhost/online-exam-result/admin/login.php
  • Login with: Username: admin, Password: admin123

Step 7: Add Sample Data via Admin

  1. Login to admin panel
  2. Go to Manage Exams β†’ Add New Exam
  3. Add exam details
  4. Go to Manage Students β†’ Add students
  5. Go to Manage Results β†’ Add results for students

Step 8: Customize Institute Details

Edit includes/config.php to update:

define('INSTITUTE_NAME', 'Your Institute Name');
define('SITE_NAME', 'Your Site Name');

🎯 Features Summary

Student Features:

  • βœ… Secure result access with roll number and DOB
  • βœ… View detailed subject-wise marks
  • βœ… Overall percentage and grade calculation
  • βœ… Download result as PDF
  • βœ… View result history
  • βœ… Mobile responsive design

Admin Features:

  • βœ… Secure login system
  • βœ… Dashboard with statistics
  • βœ… Manage exams (CRUD)
  • βœ… Manage students (CRUD)
  • βœ… Add/Edit/Delete results
  • βœ… Bulk import via CSV
  • βœ… Generate merit lists
  • βœ… Export reports
  • βœ… View toppers
  • βœ… Result publication control

Technical Features:

  • βœ… Secure password hashing
  • βœ… Session management
  • βœ… SQL injection prevention
  • βœ… XSS protection
  • βœ… Responsive design
  • βœ… PDF generation
  • βœ… CSV import/export
  • βœ… Grade calculation system

πŸš€ Future Enhancements

  1. SMS Integration: Send result notifications via SMS
  2. Graphical Reports: Charts and graphs for performance analysis
  3. Parent Portal: Parents can view their child's results
  4. Online Payment: Integration for exam fee payment
  5. Result Analytics: Advanced analytics with trends
  6. Multi-language Support: Interface in multiple languages
  7. Mobile App: Native Android/iOS apps
  8. QR Code Result Access: Scan QR code to view result
  9. Result Verification System: Verify result authenticity
  10. API Integration: REST API for third-party apps
  11. Email Notifications: Automated email on result publication
  12. Comparative Analysis: Compare with class average
  13. Subject-wise Toppers: Recognize top performers
  14. Attendance Integration: Link with attendance system
  15. Backup & Restore: Automated database backup

This comprehensive Online Exam Result System provides a complete solution for educational institutions to manage and publish exam results efficiently!

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper