Skip to main content

Online Exam System with PHP & MySQL

In our previous PHP project tutorial, we have developed Customer Relationship Management (CRM) System with PHP and MySQL. In this tutorial, we will develop Online Exam System with PHP and MySQL.

The Online exam system is a web application that can be used education purpose. The exam system allows to create complete exams with questions and its options. The exam access are given to users to complete exams in a given time. The system also allows its users to see their exam result.

The online exam systems are always in demand because most of exams or test are conducted online. So if you’re a developer and looking for solution to develop your online exam system then you’re here the right place. In this tutorial you will learn how to develop your own online exam system with PHP and MySQL.

Also, read:

Here we will develop a online exam system and cover following.

The Administrator can do the following:

  • Add/Edit Exams with questions and options.
  • Manage users.

The users can do the following:

  • Enroll to Exams.
  • View Own Exams.
  • Complete Exams.
  • View Exam Results.

So let’s start developing CRM system with PHP and MySQL. The major files are:

  • user.php
  • exam.php
  • enroll.php
  • questions.php
  • view.php
  • process_exam.php
  • User.php: A class contains users methods.
  • Exam.php: A class contains methods related to exams.
  • Questions.php: A class contains methods related to questions.

Step1: Create MySQL Database Table

First we will create MySQL database tables for our online exam system. The major tables are following.

We will create online_exam_user table to store users information.

CREATE TABLE `online_exam_user` (
  `id` int(11) UNSIGNED NOT NULL,
  `first_name` varchar(255) DEFAULT NULL,
  `last_name` varchar(255) DEFAULT NULL,
  `gender` enum('Male','Female') NOT NULL,
  `email` varchar(255) DEFAULT NULL,
  `password` varchar(64) NOT NULL,
  `mobile` varchar(12) NOT NULL,
  `address` text NOT NULL,
  `created` datetime NOT NULL DEFAULT current_timestamp(),  
  `role` enum('user','admin') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

We will create online_exam_exams table to store exams information.

CREATE TABLE `online_exam_exams` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `exam_title` varchar(250) NOT NULL,
  `exam_datetime` datetime NOT NULL,
  `duration` varchar(30) NOT NULL,
  `total_question` int(5) NOT NULL,
  `marks_per_right_answer` varchar(30) NOT NULL,
  `marks_per_wrong_answer` varchar(30) NOT NULL,
  `created_on` datetime NOT NULL,
  `status` enum('Pending','Created','Started','Completed') NOT NULL,
  `exam_code` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

We will create online_exam_question table to store exams questions information.

CREATE TABLE `online_exam_question` (
  `id` int(11) NOT NULL,
  `exam_id` int(11) NOT NULL,
  `question` text NOT NULL,
  `answer` enum('1','2','3','4') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

We will create online_exam_option table to store questions options information.

CREATE TABLE `online_exam_option` (
  `id` int(11) NOT NULL,
  `question_id` int(11) NOT NULL,
  `option` int(2) NOT NULL,
  `title` varchar(250) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

and we will create online_exam_question_answer table to store exam questions answer information.

CREATE TABLE `online_exam_question_answer` (
  `id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `exam_id` int(11) NOT NULL,
  `question_id` int(11) NOT NULL,
  `user_answer_option` enum('0','1','2','3','4') NOT NULL,
  `marks` varchar(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Step2: Manage Exam Section

We will implement functionality in exam.php file to manage exams. We will create HTML to add, edit and delete exams.

<div> 	
	<div class="panel-heading">
		<div class="row">
			<div class="col-md-10">
				<h3 class="panel-title"></h3>
			</div>
			<div class="col-md-2" align="right">
				<button type="button" id="addExam" class="btn btn-info" title="Add Exam"><span class="glyphicon glyphicon-plus"></span></button>
			</div>
		</div>
	</div>
	<table id="examListing" class="table table-bordered table-striped">
		<thead>
			<tr>						
				<th>Id</th>					
				<th>Exam Title</th>					
				<th>Date Time</th>
				<th>Duration</th>
				<th>Total Question</th>
				<th>R/Q Mark</th>
				<th>W/Q Mark</th>					
				<th>Status</th>	
				<th>Questions</th>	
				<th>Enroll</th>
				<th>Result</th>	
				<th></th>
				<th></th>					
			</tr>
		</thead>
	</table>
</div>

<div id="examModal" class="modal fade">
	<div class="modal-dialog">
		<form method="post" id="examForm">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal">×</button>
					<h4 class="modal-title"><i class="fa fa-plus"></i> Edit Exam</h4>
				</div>
				<div class="modal-body">
					<div class="form-group"
						<label for="project" class="control-label">Examm Title</label>
						<input type="text" class="form-control" id="exam_title" name="exam_title" placeholder="Exam title" required>			
					</div>

					<div class="form-group"
						<label for="project" class="control-label">Due Date</label>
						<input type="datetime-local" class="form-control" id="exam_datetime" name="exam_datetime" placeholder="Exam date" >			
					</div>	
					
					<div class="form-group"
						<label for="project" class="control-label">Duration</label>
						<select name="exam_duration" id="exam_duration" class="form-control">
								<option value="">Select</option>
								<option value="5">5 Minute</option>
								<option value="30">30 Minute</option>
								<option value="60">1 Hour</option>
								<option value="120">2 Hour</option>
								<option value="180">3 Hour</option>
							</select>	
					</div>
					
					<div class="form-group"
						<label for="project" class="control-label">Total Question</label>
						<select name="total_question" id="total_question" class="form-control">
							<option value="">Select</option>
							<option value="5">5 Question</option>
							<option value="10">10 Question</option>
							<option value="25">25 Question</option>
							<option value="50">50 Question</option>
							<option value="100">100 Question</option>
							<option value="200">200 Question</option>
							<option value="300">300 Question</option>
						</select>		
					</div>
					
					<div class="form-group"
						<label for="project" class="control-label">Marks For Right Answer</label>
						<select name="marks_right_answer" id="marks_right_answer" class="form-control">
							<option value="">Select</option>
							<option value="1">+1 Mark</option>
							<option value="2">+2 Mark</option>
							<option value="3">+3 Mark</option>
							<option value="4">+4 Mark</option>
							<option value="5">+5 Mark</option>
						</select>			
					</div>
					
					<div class="form-group"
						<label for="project" class="control-label">Marks For Wrong Answer</label>
						<select name="marks_wrong_answer" id="marks_wrong_answer" class="form-control">
							<option value="">Select</option>
							<option value="1">-1 Mark</option>
							<option value="1.25">-1.25 Mark</option>
							<option value="1.50">-1.50 Mark</option>
							<option value="2">-2 Mark</option>
						</select>			
					</div>
							
				</div>
				<div class="modal-footer">
					<input type="hidden" name="id" id="id" />
					<input type="hidden" name="action" id="action" value="" />
					<input type="submit" name="save" id="save" class="btn btn-info" value="Save" />
					<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
				</div>
			</div>
		</form>
	</div>
</div>

We will implement functionality in exam.js to open add new exam form modal to add new exam.

$('#addExam').click(function(){
	$('#examModal').modal({
		backdrop: 'static',
		keyboard: false
	});
	$('#examForm')[0].reset();
	$("#examModal").on("shown.bs.modal", function () { 
		$('.modal-title').html("<i class='fa fa-plus'></i> Add Exam");			
		$('#action').val('addExam');
		$('#save').val('Save');
	});
});		

In exam_action.php file, we will check for add exam action and calll method insert() from class Exam.php to add exam.

if(!empty($_POST['action']) && $_POST['action'] == 'addExam') {	
	$exam->exam_title = $_POST["exam_title"];
    $exam->exam_datetime = $_POST["exam_datetime"];
	$exam->duration = $_POST["exam_duration"];
	$exam->total_question = $_POST["total_question"];
	$exam->marks_per_right_answer = $_POST["marks_right_answer"];
	$exam->marks_per_wrong_answer = $_POST["marks_wrong_answer"];
	$exam->insert();
}

We will implement the method insert() in class Exam.php to add new exam to database.

public function insert(){
		
	if($this->exam_title) {

		$stmt = $this->conn->prepare("
		INSERT INTO ".$this->examTable."(`user_id`, `exam_title`, `exam_datetime`, `duration`, `total_question`, `marks_per_right_answer`,`marks_per_wrong_answer`)
		VALUES(?,?,?,?,?,?,?)");
	
		$this->exam_title = htmlspecialchars(strip_tags($this->exam_title));
		$this->exam_datetime = htmlspecialchars(strip_tags($this->exam_datetime));
		$this->duration = htmlspecialchars(strip_tags($this->duration));
		$this->total_question = htmlspecialchars(strip_tags($this->total_question));
		$this->marks_per_right_answer = htmlspecialchars(strip_tags($this->marks_per_right_answer));
		$this->marks_per_wrong_answer = htmlspecialchars(strip_tags($this->marks_per_wrong_answer));				
		
		$stmt->bind_param("isssiss", $_SESSION["userid"], $this->exam_title, $this->exam_datetime, $this->duration, $this->total_question, $this->marks_per_right_answer, $this->marks_per_wrong_answer);
		
		if($stmt->execute()){
			return true;
		}		
	}
}

We will implement the method update() in class Exam.php to update the exam.

public function update(){
		
	if($this->id && $_SESSION["userid"]) {	
		
		$stmt = $this->conn->prepare("
		UPDATE ".$this->examTable." 
		SET exam_title= ?, exam_datetime = ?, duration = ?, total_question = ?, marks_per_right_answer = ?, marks_per_wrong_answer = ?
		WHERE id = ? AND user_id = ?");
 
		$this->id = htmlspecialchars(strip_tags($this->id));
		$this->exam_title = htmlspecialchars(strip_tags($this->exam_title));
		$this->exam_datetime = htmlspecialchars(strip_tags($this->exam_datetime));
		$this->duration = htmlspecialchars(strip_tags($this->duration));
		$this->total_question = htmlspecialchars(strip_tags($this->total_question));
		$this->marks_per_right_answer = htmlspecialchars(strip_tags($this->marks_per_right_answer));
		$this->marks_per_wrong_answer = htmlspecialchars(strip_tags($this->marks_per_wrong_answer));				
		
		$stmt->bind_param("sssissii", $this->exam_title, $this->exam_datetime, $this->duration, $this->total_question, $this->marks_per_right_answer, $this->marks_per_wrong_answer, $this->id, $_SESSION["userid"]);
		
		if($stmt->execute()){
			return true;
		}
		
	}	
}	

We will implement the method delete() in class Exam.php to delete the exam.

public function delete(){
	if($this->id && $_SESSION["userid"]) {			

		$stmt = $this->conn->prepare("
			DELETE FROM ".$this->examTable." 
			WHERE id = ? AND user_id = ?");

		$this->id = htmlspecialchars(strip_tags($this->id));

		$stmt->bind_param("ii", $this->id, $_SESSION["userid"]);

		if($stmt->execute()){
			return true;
		}
	}
}

We will also implement the method listExam() in class Exam.php to list all exam.

public function listExam(){			
	$sqlQuery = "
		SELECT id, exam_title, exam_datetime, duration, total_question, marks_per_right_answer, marks_per_wrong_answer, status
		FROM ".$this->examTable." 
		WHERE user_id = '".$_SESSION["userid"]."' ";
	if(!empty($_POST["search"]["value"])){
		$sqlQuery .= ' AND (name LIKE "%'.$_POST["search"]["value"].'%" ';			
		$sqlQuery .= ' OR email LIKE "%'.$_POST["search"]["value"].'%" ';
		$sqlQuery .= ' OR gender LIKE "%'.$_POST["search"]["value"].'%" ';
		$sqlQuery .= ' OR mobile LIKE "%'.$_POST["search"]["value"].'%" ';
		$sqlQuery .= ' OR address LIKE "%'.$_POST["search"]["value"].'%" ';				
		$sqlQuery .= ' OR age LIKE "%'.$_POST["search"]["value"].'%") ';							
	}
	
	if(!empty($_POST["order"])){
		$sqlQuery .= 'ORDER BY '.$_POST['order']['0']['column'].' '.$_POST['order']['0']['dir'].' ';
	} else {
		$sqlQuery .= 'ORDER BY id ASC ';
	}
	
	if($_POST["length"] != -1){
		$sqlQuery .= 'LIMIT ' . $_POST['start'] . ', ' . $_POST['length'];
	}
	
	$stmt = $this->conn->prepare($sqlQuery);
	$stmt->execute();
	$result = $stmt->get_result();	
	
	$stmtTotal = $this->conn->prepare("SELECT * FROM ".$this->examTable." WHERE id = '".$_SESSION["userid"]."'");
	$stmtTotal->execute();
	$allResult = $stmtTotal->get_result();
	$allRecords = $allResult->num_rows;
	
	$displayRecords = $result->num_rows;
	$records = array();	

	while ($exam = $result->fetch_assoc()) { 				
		$rows = array();			
		$rows[] = $exam['id'];
		$rows[] = $exam['exam_title'];
		$rows[] = $exam['exam_datetime'];
		$rows[] = $exam['duration'];
		$rows[] = $exam['total_question'];
		$rows[] = $exam['marks_per_right_answer'];	
		$rows[] = $exam['marks_per_wrong_answer'];			
		$rows[] = $exam['status'];			
		$rows[] = '<a type="button" name="view" href="questions.php?exam_id='.$exam["id"].'" class="btn btn-info btn-xs add_question"><span class="glyphicon" title="Add Question">Questions</span></a>';			
		$rows[] = '<a type="button" name="update" href="enroll.php?exam_id='.$exam["id"].'" class="btn btn-primary btn-xs enroll"><span class="glyphicon glyphicon-user" title="Enroll">Enroll</span></a>';
		$rows[] = '<button type="button" name="delete" id="'.$exam["id"].'" class="btn btn-success btn-xs result" ><span class="glyphicon" title="Result">Result</span></button>';
		$rows[] = '<button type="button" name="update" id="'.$exam["id"].'" class="btn btn-warning btn-xs update"><span class="glyphicon glyphicon-edit" title="Edit"></span></button>';			
		$rows[] = '<button type="button" name="delete" id="'.$exam["id"].'" class="btn btn-danger btn-xs delete" ><span class="glyphicon glyphicon-remove" title="Delete"></span></button>';		
		$records[] = $rows;
	}
	
	$output = array(
		"draw"	=>	intval($_POST["draw"]),			
		"iTotalRecords"	=> 	$displayRecords,
		"iTotalDisplayRecords"	=>  $allRecords,
		"data"	=> 	$records
	);
	
	echo json_encode($output);
}

Step3: Manage Exam Questions

We will create the HTML to implement the functionaloity in questions.php to add, edit and delete the questions. We will also handle the functionality to add question options.

<nav aria-label="breadcrumb">
	<ol class="breadcrumb">
		<li class="breadcrumb-item"><a href="exam.php">Exam</a></li>
		<li class="breadcrumb-item active" aria-current="page">Questions</li>
	</ol>
</nav>
<br>	
<div> 	
	<div class="panel-heading">
		<div class="row">
			<div class="col-md-10">
				<h3 class="panel-title"></h3>
			</div>
			<div class="col-md-2" align="right">
				<button type="button" id="addQuestions" class="btn btn-info" title="Add Questions"><span class="glyphicon glyphicon-plus"></span></button>
			</div>
		</div>
	</div>
	<table id="questionsListing" data-exam-id="<?php echo $_GET['exam_id']; ?>" class="table table-bordered table-striped">
		<thead>
			<tr>						
				<th>Id</th>					
				<th>Question</th>					
				<th>Right Option</th>					
				<th></th>
				<th></th>					
			</tr>
		</thead>
	</table>
</div>

<div id="questionsModal" class="modal fade">
	<div class="modal-dialog">
		<form method="post" id="questionsForm">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal">×</button>
					<h4 class="modal-title"><i class="fa fa-plus"></i> Edit questions</h4>
				</div>
				<div class="modal-body">
					
					<div class="form-group">
						<div class="row">
							<label class="col-md-4 text-right">Question Title <span class="text-danger">*</span></label>
							<div class="col-md-8">
								<input type="text" name="question_title" id="question_title" autocomplete="off" class="form-control" />
							</div>
						</div>
					</div>
					
					<div class="form-group">
						<div class="row">
							<label class="col-md-4 text-right">Option 1 <span class="text-danger">*</span></label>
							<div class="col-md-8">
								<input type="text" name="option_title_1" id="option_title_1" autocomplete="off" class="form-control" />
							</div>
						</div>
					</div>
					<div class="form-group">
						<div class="row">
							<label class="col-md-4 text-right">Option 2 <span class="text-danger">*</span></label>
							<div class="col-md-8">
								<input type="text" name="option_title_2" id="option_title_2" autocomplete="off" class="form-control" />
							</div>
						</div>
					</div>
					<div class="form-group">
						<div class="row">
							<label class="col-md-4 text-right">Option 3 <span class="text-danger">*</span></label>
							<div class="col-md-8">
								<input type="text" name="option_title_3" id="option_title_3" autocomplete="off" class="form-control" />
							</div>
						</div>
					</div>
					<div class="form-group">
						<div class="row">
							<label class="col-md-4 text-right">Option 4 <span class="text-danger">*</span></label>
							<div class="col-md-8">
								<input type="text" name="option_title_4" id="option_title_4" autocomplete="off" class="form-control" />
							</div>
						</div>
					</div>
					<div class="form-group">
						<div class="row">
							<label class="col-md-4 text-right">Answer <span class="text-danger">*</span></label>
							<div class="col-md-8">
								<select name="answer_option" id="answer_option" class="form-control">
									<option value="">Select</option>
									<option value="1">1 Option</option>
									<option value="2">2 Option</option>
									<option value="3">3 Option</option>
									<option value="4">4 Option</option>
								</select>
							</div>
						</div>
					</div>					
							
				</div>
				<div class="modal-footer">
					<input type="hidden" name="id" id="id" />
					<input type="hidden" name="exam_id" id="exam_id" />
					<input type="hidden" name="action" id="action" value="" />
					<input type="submit" name="save" id="save" class="btn btn-info" value="Save" />
					<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
				</div>
			</div>
		</form>
	</div>
</div>

In questions.js, we will implement the functionality to open the question add modal.

$('#addQuestions').click(function(){
	$('#questionsModal').modal({
		backdrop: 'static',
		keyboard: false
	});		
	$("#questionsModal").on("shown.bs.modal", function () {
		$('#questionsForm')[0].reset();			
		$('.modal-title').html("<i class='fa fa-plus'></i> Add Questions");
		$('#exam_id').val($('#questionsListing').attr('data-exam-id'));			
		$('#action').val('addQuestions');
		$('#save').val('Save');
	});
});	

We will check for action addQuestions and implement the functionality to call method insert() from class Questions.php to add questions with options.

if(!empty($_POST['action']) && $_POST['action'] == 'addQuestions') {
	$questions->exam_id = $_POST["exam_id"];	
	$questions->question_title = $_POST["question_title"];
	$options = array();	
	for($count = 1; $count <= 4; $count++) {
		$options[$count] = $_POST['option_title_' . $count];
	}
	$questions->option = $options;    
	$questions->answer_option = $_POST["answer_option"];
	$questions->insert();
}

We will implement the method insert() in class Questions.php to add question with options.

public function insert(){
		
	if($this->exam_id && $this->question_title && $this->answer_option) {

		$stmt = $this->conn->prepare("
			INSERT INTO ".$this->questionTable."(`exam_id`, `question`, `answer`)
			VALUES(?,?,?)");
	
		$this->question_title = htmlspecialchars(strip_tags($this->question_title));
		$this->answer_option  = htmlspecialchars(strip_tags($this->answer_option));			
		$stmt->bind_param("iss", $this->exam_id, $this->question_title, $this->answer_option);
		
		if($stmt->execute()){
			$lastInsertQuestionId = $this->conn->insert_id;
			$stmt1 = $this->conn->prepare("
				INSERT INTO ".$this->optionTable."(`question_id`, `option`, `title`)
				VALUES(?,?,?)");				
			foreach($this->option as $key => $value) {					
				$stmt1->bind_param("iis", $lastInsertQuestionId, $key, $value);
				$stmt1->execute();
			}
			return true;
		}		
	}
}

Step4: Implement Enroll to Exam

We will create HTML to display exam dropdown list to allow users to enroll to exams to complete exam.

<div class="row">
	<div class="col-md-3"></div>
	<div class="col-md-6">
		<select name="exam_list" id="exam_list" class="form-control input-lg">
			<option value="">Select Exam</option>
			<?php echo $exam->getExamList(); ?>
		</select>
		<br />
		<span id="exam_details"></span>
	</div>
	<div class="col-md-3"></div>
</div>

We will implement the functionality to enroll to exam.

$(document).on('click', '#enrollExam', function(){
	var exam_id = $('#enrollExam').attr('data-exam_id');		
	$.ajax({
		url:"user_exam_action.php",
		method:"POST",
		data:{action:'enrollExam', exam_id:exam_id},
		beforeSend:function() {
			$('#enrollExam').attr('disabled', 'disabled');
			$('#enrollExam').text('please wait');
		},
		success:function() {
			$('#enrollExam').attr('disabled', false);
			$('#enrollExam').removeClass('btn-warning');
			$('#enrollExam').addClass('btn-success');
			$('#enrollExam').text('Enroll success');
		}
	});
});

In user_exam_action.php, we will check for action enrollExam and call method enrollToExam() from class Exam.php to enroll to exam.

if(!empty($_POST['action']) && $_POST['action'] == 'enrollExam') {
	$exam->exam_id = $_POST['exam_id'];
	$exam->enrollToExam();
}

We will implement the method enrollToExam() in class Exam.php to enroll exam to user to complete it.

public function enrollToExam(){
		
	if($this->exam_id) {

		$stmt = $this->conn->prepare("
		INSERT INTO ".$this->enrollTable."(`user_id`, `exam_id`)
		VALUES(?,?)");
	
		$this->exam_id = htmlspecialchars(strip_tags($this->exam_id));
								
		$stmt->bind_param("ii", $_SESSION["userid"], $this->exam_id);
		
		if($stmt->execute()){
			
			$stmtAnswer = $this->conn->prepare("
				INSERT INTO ".$this->questionAnswerTable."(`user_id`, `exam_id`, `question_id`)
				VALUES(?,?,?)");
				
			$sqlQuery = "
				SELECT id
				FROM ".$this->questionTable."
				WHERE exam_id = ?";	
			$stmtQuestion = $this->conn->prepare($sqlQuery);
			$stmtQuestion->bind_param("i", $this->exam_id);
			$stmtQuestion->execute();
			$result = $stmtQuestion->get_result();				
			while ($question = $result->fetch_assoc()) {					
				$stmtAnswer->bind_param("iii", $_SESSION["userid"], $this->exam_id, $question['id']);
				$stmtAnswer->execute();
			}
			return true;
		}		
	}
}

Step5: Implement View Exam

We will create the HTML to display exam questions with options to complete the exam. We will also display the question time with timer to display the exam remaining time to complete the exam within that time.

<?php 
if($examDetails['status'] == 'Started') {
?>	
	<div class="col-md-8">
		<div class="card">			
			<div class="card-body">
				<div id="single_question_area"></div>
			</div>
		</div>
		<br />
		<div id="question_navigation_area"></div>
	</div>
	<div class="col-md-4">
		<br />
		<div align="center">
			<div id="examTimer" data-timer="<?php echo $remainingMinutes; ?>" style="max-width:400px; width: 100%; height: 200px;"></div>
		</div>
		<br />
		<div id="user_details_area"></div>		
	</div>
<?php } ?>	

We will implement the function loadQuestion() in user_exam_action.php to load the exam questions.

function loadQuestion(question_id = '') {
	var examId = $('#processExamId').attr('data-exam_id');
	$.ajax({
		url:"user_exam_action.php",
		method:"POST",
		data:{exam_id:examId, question_id:question_id, action:'loadQuestion'},
		success:function(data){			
			$('#single_question_area').html(data);
		}
	})
}

We will check for the action loadQuestion and call method loadQuestions() from class Exam.php to load exam questions.

if(!empty($_POST['action']) && $_POST['action'] == 'loadQuestion') {
	$exam->exam_id = $_POST['exam_id'];
	$exam->question_id = $_POST['question_id'];
	$exam->loadQuestions();
}

We will implement the method loadQuestions() in class Exam.php to load exam questions with options.

public function loadQuestions() {
	if($this->exam_id) {
		
		$whereSql = '';
		if($this->question_id) {
			$whereSql = "questions.id = '".$this->question_id."'";
		} elseif($this->exam_id) {
			$whereSql = "questions.exam_id = '".$this->exam_id."'";
		}
		
		$sqlQuery = "
			SELECT questions.id as question_id, questions.question, questions.answer
			FROM ".$this->questionTable." AS questions 
			WHERE $whereSql ORDER BY questions.id ASC LIMIT 1";			
		
		$stmtQuestion = $this->conn->prepare("
			SELECT * FROM ".$this->optionTable." 
			WHERE question_id = ?");
			
		$sqlQueryPrev = $this->conn->prepare("
			SELECT id
			FROM ".$this->questionTable." 
			WHERE id < ? AND exam_id = ? ORDER BY id DESC LIMIT 1");
		
		$sqlQueryNext = $this->conn->prepare("
			SELECT id
			FROM ".$this->questionTable." 
			WHERE id > ? AND exam_id = ? ORDER BY id ASC LIMIT 1");
					
		$stmt = $this->conn->prepare($sqlQuery);			
		$stmt->execute();
		$result = $stmt->get_result();				
		$output = '';
		while ($questions = $result->fetch_assoc()) {
			$output .= '
			<h2>'.$questions["question"].'</h2>
			<hr />
			<div class="row">';
			
			$stmtQuestion->bind_param("i", $questions["question_id"]);	
			$stmtQuestion->execute();
			$resultQuestion = $stmtQuestion->get_result();
			$count = 1;
			while ($options = $resultQuestion->fetch_assoc()) {
				
				$output .= '
				<div class="col-md-6" style="margin-bottom:32px;">
					<div class="radio">
						<label><h4><input type="radio" name="option_1" class="answer_option" data-question_id="'.$questions["question_id"].'" data-id="'.$count.'"/> '.$options["title"].'</h4></label>
					</div>
				</div>';

				$count = $count + 1;
			}				
		
		$output .= '</div>';
			
					
		$sqlQueryPrev->bind_param("ii", $questions["question_id"], $this->exam_id);	
		$sqlQueryPrev->execute();
		$resultPrev = $sqlQueryPrev->get_result();
		
		$previousId = '';
		$nextId = '';
		while ($preQuestion = $resultPrev->fetch_assoc()) {
			$previousId = $preQuestion['id'];
		}	
		
		$sqlQueryNext->bind_param("ii", $questions["question_id"], $this->exam_id);	
		$sqlQueryNext->execute();
		$resultNext = $sqlQueryNext->get_result();
		
		while ($nextQuestion = $resultNext->fetch_assoc()) {
			$nextId = $nextQuestion['id'];
		}	
		
		$previousDisable = '';
		$nextDisable = '';

		if($previousId == "") {
			$previousDisable = 'disabled';
		}
		
		if($nextId == "") {
			$nextDisable = 'disabled';
		}
			
		$output .= '
			<br /><br />
			<div>
				<button type="button" name="previous" class="btn btn-info btn-lg previous" id="'.$previousId.'" '.$previousDisable.'>Previous</button>
				<button type="button" name="next" class="btn btn-warning btn-lg next" id="'.$nextId.'" '.$nextDisable.'>Next</button>
			</div>
			<br /><br />';
		}
		echo $output;
	}
}

You may also like:

You can view the live demo from the Demo link and can download the script from the Download link below.
Demo Download

6 thoughts on “Online Exam System with PHP & MySQL

  1. I’m sorry… after I sent the message I found the button download code thank you very much..
    please ignore my previous message

  2. Dear Friend
    When i download your demo and install the database and everything on xamp local host . When i enroll with user to java test and try to run – view the test not work. I dont see the questions. Only a white page. I tested with firefox and chrome

Comments are closed.