项目体验
点击连接即可考试 已有的用户:范冰冰 学生 编号:190901102 密码:111111 已有教师:admin(编号、姓名和密码都为admin) 也可以自行注册用户
1、前言
1.1、编写目的
明确本项目功能,简单的介绍了本系统的设计思想,基本功能,模块划分,以便于开发人员更好的了解改系统
1.2、项目需求
提供用户(学生&教师)登录,用户权限(分教师与学生端),教师出卷子,学生写卷子。学生答题后显示答案与分数,并记录在历史成绩中(教师查看),提供教师二次批改试卷
1.3、项目环境及其功能
操作系统:Windows 10/7 运行环境:装有xampp的电脑即可
2、模块分析 & 数据表
2.1、学生&教师信息
student_id | student_name | student_password | student_sj | student_answer | student_stdf | student_cj | date |
---|
用户id | 用户名 | 密码 | 科目 | 学生答题答案 | 正确答案 | 考试成绩 | 作答时间 |
teacher_id | teacher_name | teacher_password | teacher_sj | data |
---|
教师id | 教师用户名 | 密码 | 科目 | 出卷时间 |
2.2、登录 & 注册 & 找回密码
(1)登录login.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>用户登录</title>
<link rel="stylesheet" href="../css/layout.css">
</head>
<body>
<div class="login">
<div class="login-wrap">
<div class="login-box">
<form method="post" action="../login.php">
<table>
<tr><th>编号:</th><td><input type="text" name="no" value="190901102" required></td></tr>
<tr><th>姓名:</th><td><input type="text" name="name" value="范冰冰" required></td></tr>
<tr><th>密码:</th><td><input type="password" name="password" value="111111" required></td></tr>
<tr><th>身份:</th><td><select type="text" name="usageid" style=width:260px;height:30px;padding:3px 4px;font-size:20px;border:1px solid #ddd;color:#666><option value="student">学生</option><option value="teacher">教师</option></select></td></tr>
<tr><th>验证码:</th><td><input type="text" name="code"></td></tr>
<tr><th></th><td><img src="../common/validcode.php" style="width:150px;height:40px;" id="code"/>
<a href="javascript:changeCode()">看不清,换一张</a>
<tr class="m-reg-act"><th></th><td><input type="submit" value="立即登录">
<span> 没有账号?<a href="./register.html" target="_blank" >立即注册</a></span>
<span> 忘记密码?<a href="./find.html" target="_blank">找回密码</a></span>
</table>
</form>
</div>
</div>
</div>
<script type="text/javascript">
function changeCode() {
document.getElementById("code").src = "../common/validcode.php?id=" + Math.random();
}
</script>
</body>
</html>
(2)注册register.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>用户注册</title>
<link rel="stylesheet" href="../css/dashicons.css">
<link rel="stylesheet" href="../css/layout.css">
<script src="../js/jquery.min.js"></script>
<script>
if(top.location !== self.location){
top.location = self.location;
}
</script>
</head>
<body>
<div class="top">
<div class="top-title icon-home">用户注册</div>
</div>
<div class="login">
<div class="login-wrap">
<div class="login-box">
<form method="post" action="../register.php" >
<table>
<tr><th>编号:</th><td><input type="text" name="no" placeholder="请输入编号" required></td></tr>
<tr><th>姓名:</th><td><input type="text" name="name" placeholder="请输入姓名" required></td></tr>
<tr><th>密码:</th><td><input type="password" name="password" id="pw1" placeholder="请输入6位以上的密码" required></td></tr>
<tr><th>确认密码:</th><td><input type="password" id="pw2" onBlur="check()" placeholder="请再次输入密码,进行确认" required></td></tr>
<tr><th>电话:</th><td><input type="text" name="tel" id="phone" onBlur="checkphone()" placeholder="请输入电话号码" required></td></tr>
<tr><th>QQ:</th><td><input type="text" name="email" placeholder="请输入qq号" required></td></tr>
<tr><th>身份:</th><td><select type="text" name="usageid" style=width:260px;height:30px;padding:3px 4px;font-size:20px;border:1px solid #ddd;color:#666><option value="student">学生</option><option value="teacher">教师</option></select></td></tr>
<tr><th>验证码:</th><td><input type="text" name="code" placeholder="请输入验证码" required></td></tr>
<tr><th></th><td><img src="../common/validcode.php" style="width:150px;height:40px;" id="code"/>
<a href="javascript:changeCode()">看不清,换一张</a></td></tr>
<tr><th></th><td><p>
<tr class="m-reg-act"><th></th><td><input type="submit" value="确认注册"><span>已经有账号?<a href="./login.html">立即登录</a></span></td></tr>
</table>
</form>
</div>
</div></div>
<script type="text/javascript">
function $(id)
{
return document.getElementById(id)
}
function check()
{
var boo=$('pw1').value==$('pw2').value;
if (boo)
{
$teacher_password=$_SESSION["pw1"];
return true;
}
else
{
alert('两次密码不一致');
}
}
function changeCode()
{
document.getElementById("code").src = "../common/validcode.php?id=" + Math.random();jisuanjikexueyujishu
}
function checkphone($tel)
{
var phone=document.getElementById("phone").value;
if(!(/^[1]\d{10}$/.test(phone)))
{
alert("电话号码格式不对,必须1开头且总长度位11位数字");
}
else
{
return ture;
}
}
</script>
(3)找回密码find.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>用户密码找回</title>
<link rel="stylesheet" href="../css/dashicons.css">
<link rel="stylesheet" href="../css/layout.css">
<script src="../js/jquery.min.js"></script>
<script>
if(top.location !== self.location){
top.location = self.location;
}
</script>
</head>
<body>
<div class="top">
<div class="top-title icon-home">用户密码找回</div>
</div>
<div class="login">
<div class="login-wrap">
<div class="login-box">
<form method="post" action="../find.php" >
<table>
<tr><th>编号:</th><td><input type="text" name="no" placeholder="请输入要找回的编号" required></td></tr>
<tr><th>姓名:</th><td><input type="text" name="name" placeholder="请输入该编号绑定的姓名" required></td></tr>
<tr><th>电话:</th><td><input type="text" name="tel" id="phone" onBlur="checkphone()" placeholder="请输入绑定的电话号码" required></td></tr>
<tr><th>QQ:</th><td><input type="text" name="email" placeholder="请输入绑定的QQ号" required></td></tr>
<tr><th>验证码:</th><td><input type="text" name="code" placeholder="请输入验证码" required></td></tr>
<tr><th></th><td><img src="../common/validcode.php" style="width:150px;height:40px;" id="code"/>
<a href="javascript:changeCode()">看不清,换一张</a></td></tr>
<tr><th></th><td><p>
<tr class="m-reg-act"><th></th><td><input type="submit" value="确认找回"><span>已找回密码?<a href="./login.html">立即登录</a></span></td></tr>
</table>
</form>
</div>
</div></div>
<script type="text/javascript">
function changeCode()
{
document.getElementById("code").src = "../common/validcode.php?id=" + Math.random();jisuanjikexueyujishu
}
function checkphone($tel)
{
var phone=document.getElementById("phone").value;
if(!(/^[1]\d{10}$/.test(phone)))
{
alert("电话号码格式不对,必须1开头且总长度为11位数字");
}
else
{
return ture;
}
}
</script>
2.3、试卷页面 & 题目数据表
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?=$data['title']?> - 在线考试系统</title>
<link rel="stylesheet" href="css/style.css">
<script src="js/jquery.min.js"></script>
<script src="js/jquery.timeout.js"></script>
<script>
$(function(){
$(window).on("beforeunload",function(){
return "您尚未交卷!此操作将导致您的回答丢失。";
});
timeOver = false;
$(".timeout").timeout({
"maxTime":<?=$data['timeout']?>,
"onTimeOver":function(){
timeOver = true;
alert("考试时间结束,系统自动交卷。");
$("#testForm").submit();
}
});
$("#testForm").submit(function(event){
$(window).off("beforeunload");
timeOver || checkMultiple(event);
});
function checkMultiple(event){
$(".jq-multiple .question-each").each(function(){
if($(this).find(".question-option input[type=checkbox]:checked").length < 1){
$(this).find(".question-option input[type=checkbox]:first").focus();
event.preventDefault();
alert('您有多选题未作答');
return false;
}
});
};
});
</script>
</head>
<body>
<div class="top">
<div class="top-title">正在考试
<div style="float: right;margin-right: 20px;font-weight: normal;color: black;font-size: 13px;">
你好,<?=$name?>同学
</div>
</div>
</div>
<div class="main">
<div class="main-wrap">
<div class="question-top">
<div class="question-title"><?=$data['title']?></div>
<div class="question-nav">
<a href="#binary">判断题</a>
<a href="#single">单选题</a>
<a href="#multiple">多选题</a>
<a href="#fill">填空题</a>
<a href="#reply">简答题</a>
<a href="#complex">综合题</a>
</div>
</div>
<form action="total.php?id=<?=$id?>" method="post" id="testForm" >
<div id="binary" class="anchor" ></div>
<div class="question-wrap">
<div class="question-type">一、判断题<span>(共<?=$count['binary']?>题,每题<?=$score['binary']?>分)</span></div>
<?php foreach($data['data']['binary']['data'] as $k=>$v): ?>
<div class="question-each">
<div class="question-name"><?=$k,'. ',$v['question']?></div>
<div class="question-option">
<label><input type="radio" value="yes" name="binary[<?=$k?>]" required>对</label>
<label><input type="radio" value="no" name="binary[<?=$k?>]" required>错</label>
</div>
</div>
<?php endforeach; ?>
</div>
<div id="single" class="anchor" ></div>
<div class="question-wrap">
<div class="question-type">二、单选题<span>(共<?=$count['single']?>题,每题<?=$score['single']?>分)</span></div>
<?php foreach($data['data']['single']['data'] as $k=>$v): ?>
<div class="question-each">
<div class="question-name"><?=$k,'. ',$v['question']?></div>
<div class="question-option">
<label><input type="radio" value="A" name="single[<?=$k?>]" required>A. <?=$v['option'][0]?></label>
<label><input type="radio" value="B" name="single[<?=$k?>]" required>B. <?=$v['option'][1]?></label>
<label><input type="radio" value="C" name="single[<?=$k?>]" required>C. <?=$v['option'][2]?></label>
<label><input type="radio" value="D" name="single[<?=$k?>]" required>D. <?=$v['option'][3]?></label>
</div>
</div>
<?php endforeach; ?>
</div>
<div id="multiple" class="anchor" ></div>
<div class="question-wrap jq-multiple">
<div class="question-type">三、多选题<span>(共<?=$count['multiple']?>题,每题<?=$score['multiple']?>分)</span></div>
<?php foreach($data['data']['multiple']['data'] as $k=>$v): ?>
<div class="question-each">
<div class="question-name"><?=$k,'. ',$v['question']?></div>
<div class="question-option">
<label><input type="checkbox" value="A" name="multiple[<?=$k?>][]">A. <?=$v['option'][0]?></label>
<label><input type="checkbox" value="B" name="multiple[<?=$k?>][]">B. <?=$v['option'][1]?></label>
<label><input type="checkbox" value="C" name="multiple[<?=$k?>][]">C. <?=$v['option'][2]?></label>
<label><input type="checkbox" value="D" name="multiple[<?=$k?>][]">D. <?=$v['option'][3]?></label>
</div>
</div>
<?php endforeach; ?>
</div>
<div id="fill" class="anchor" ></div>
<div class="question-wrap">
<div class="question-type">四、填空题<span>(共<?=$count['fill']?>题,每题<?=$score['fill']?>分)</span></div>
<?php foreach($data['data']['fill']['data'] as $k=>$v): ?>
<div class="question-each">
<div class="question-name"><?=$k,'. ',$v['question']?></div>
<div class="question-option">
<span>请输入答案:<textarea name="fill[<?=$k?>]" style="width:99%;height:16px; "required></textarea></span>
</div>
</div>
<?php endforeach; ?>
</div>
<div id="reply" class="anchor" ></div>
<div class="question-wrap">
<div class="question-type">五、简答题<span>(共<?=$count['reply']?>题,每题<?=$score['reply']?>分)</span></div>
<?php foreach($data['data']['reply']['data'] as $k=>$v): ?>
<div class="question-each">
<div class="question-name"><?=$k,'. ',$v['question']?></div>
<div class="question-option">
<span>请输入答案:<textarea name="reply[<?=$k?>]" style="width:99%;height:80px; "required></textarea></span>
</div>
</div>
<?php endforeach; ?>
</div>
<div id="complex" class="anchor" ></div>
<div class="question-wrap">
<div class="question-type">六、综合题<span>(共<?=$count['complex']?>题,每题<?=$score['complex']?>分)</span></div>
<?php foreach($data['data']['complex']['data'] as $k=>$v): ?>
<div class="question-each">
<div class="question-name"><?=$k,'. ',$v['question']?></div>
<div class="question-option">
<span>请输入答案:<textarea name="complex[<?=$k?>]" style="width:99%;height:80px; "required></textarea></span>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="question-act">
<input type="submit" value="交卷" >
</div>
</form>
</div>
</div>
<div class="footer">
PHP在线考试系统 本项目仅供学习使用
</div>
</body>
</html>
数据库题目字段:
2.4、考试结束
total.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>考试结束 - 在线考试系统</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="top">
<div class="top-title">在线考试系统 - 考试结束</div>
</div>
<div class="main">
<div class="main-wrap">
<div class="main-title center"><?=$name?>同学,您的成绩:<?=$sum?>分</div>
<table class="total-table">
<tr><th>题型</th><th>题号</th><th>答题情况</th><th>得分</th></tr>
<?php foreach($total as $type=>$each): ?>
<?php if($data['data'][$type]['name']=="判断题" or $data['data'][$type]['name']=="单选题" or $data['data'][$type]['name']=="多选题" or $data['data'][$type]['name']=="填空题"): ?>
<?php foreach($each as $k=>$v): ?>
<tr>
<?php if($k==1): ?>
<td <?="rowspan=\"$count[$type]\""?>><?=$data['data'][$type]['name']?></td>
<?php endif; ?>
<td><?=$k?></td>
<td><?=$v ? '对' : '错'?></td>
<td><?=$v ? $score[$type] : 0?></td>
</tr>
<?php endforeach; ?>
<?php else: ?>
<?php foreach($each as $k=>$v): ?>
<tr>
<?php if($k==1): ?>
<td <?="rowspan=\"$count[$type]\""?>><?=$data['data'][$type]['name']?></td>
<?php endif; ?>
<td><?=$k?></td>
<td><?=$total[$type][$k] ?></td>
<?php if($data['data'][$type]['name']=="简答题"): ?>
<td><?=$reply[ $type ][ $k ] ?></td>
<?php else: ?>
<td><?=$complex[ $type ][ $k ] ?></td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php endforeach; ?>
</table>
<div class="total-act">
<a href="./">返回首页</a>
</div>
</div>
</div>
<div class="footer">
PHP在线考试系统 本项目仅供学习使用
</div>
<script language="javascript">
history.pushState(null, null, document.URL);
window.addEventListener('popstate', function () {
history.pushState(null, null, document.URL);
});
document.onkeydown = function(e) {
e = window.event || e;
var k = e.keyCode;
if ((e.ctrlKey == true && k == 82) || (k == 116)
|| (e.ctrlKey == true && k == 116)||k==114) {
e.keyCode = 0;
alert("当前页面不能刷新!");
e.returnValue = false;
e.cancelBubble = true;
return false;
}
if (k == 8) {
alert("不能返回或后退!");
e.keyCode = 0;
e.returnValue = false;
return false;
}
if (e.ctrlKey && k == 78){
e.keyCode = 0;
e.returnValue = false;
e.cancelBubble = true;
return false;
}
if (k == 122) {
e.keyCode = 0;
e.returnValue = false;
e.cancelBubble = true;
return false;
}
if ((e.shiftKey && k == 121)||(e.ctrlKey && k == 121)){
e.keyCode = 0;
e.returnValue = false;
e.cancelBubble = true;
return false;
}
if ((e.altKey) && (k== 115)) {
window.showModelessDialog("about:blank", "",
"dialogWidth:1px;dialogheight:1px");
e.keyCode = 0;
e.returnValue = false;
e.cancelBubble = true;
return false;
}
if ((e.altKey)
&& ((k == 37) || (k == 39))) {
alert("不准你使用ALT+方向键前进或后退网页!");
e.keyCode = 0;
e.returnValue = false;
e.cancelBubble = true;
return false;
}
};
document.oncontextmenu = function(event) {
if (window.event) {
event = window.event;
}
try {
var the = event.srcElement;
if (!((the.tagName == "INPUT" && the.type.toLowerCase() == "text") || the.tagName == "TEXTAREA")) {
return false;
}
return true;
} catch (e) {
return false;
}
};
</script>
</body>
</html>
2.5、教师阅卷(是要数据库添加成为学生才可以由教师阅卷)
2.6、关键技术说明
(1)1.php:
功能是随机生成试卷;方法是选取数据库中的试题序号;缺陷是如果数据表中序号间断,试卷会显示空题。
(2)2.php:
功能是读取数据库的试题;方法是用
S
E
S
S
I
O
N
[
]
接
收
1.
p
h
p
的
随
机
的
试
题
序
号
,
然
后
用
s
e
l
e
c
t
?
f
r
o
m
数
据
库
表
w
h
e
r
e
试
题
i
d
=
_SESSION[]接收1.php的随机的试题序号,然后用select * from 数据库表 where 试题id=
S?ESSION[]接收1.php的随机的试题序号,然后用select?from数据库表where试题id=_session查询。
(3)function.php:功能函数库
a、获取题库ID:
function getTestId(){
$id = isset($_GET['id']) ? (int)$_GET['id'] : 1;
return max($id, 1);
}
b、根据序号载入题库
@param int $id 题库序号
@param bool $toHTML 是否对题库进行转义
$return 如果题库存在,读取并返回数据;不存在,返回false。
function getDataById($id, $toHTML=true){
$target = "./data/$id.php";
if(!file_exists($target)){
return false;
}
$data = require $target;
$func = function($data) use(&$func){
$result = [];
foreach($data as $k=>$v){
$result[$k] = is_array($v) ? $func($v) : (is_string($v) ? toHTML($v) : $v);
}
return $result;
};
return $toHTML ? $func($data) : $data;
}
c、获取题库信息
@param array $data 题库
@param array $score 分数
$return array 每种题型的个数、每种题型下1道题的分数
function getDataInfo($data){
$count = [];
$score = [];
foreach($data as $k=>$v){
$count[$k] = count($v['data']);
$score[$k] = round($v['score'] / $count[$k]);
}
return [$count, $score];
}
d、计算总分
@params array $data 题库
$return int 总分数
function getDataTotal($data){
$sum = 0;
foreach($data as $v){
$sum += $v['score'];
}
return $sum;
}
e、将字符串编码为HTML
转换的特殊字符有:& " ' < > 和空格
未对换行符进行转换,如果需要,再调用nl2br函数即可
@param string $str 输入的字符串
@return string 编码后的字符串
function toHTML($str){
$str = htmlspecialchars($str, ENT_QUOTES);
return str_replace(' ', ' ', $str);
}
3、本地部署(运行) & 云服务器部署
3.1、本地部署
1、如果没有安装xampp的先安装xampp(会联同项目一起打包) 2、将整个test项目复制到xampp下的htdocs下如图所示 test下的如图所示: 3、运行xampp开启两个服务后点击MySQL的admin 4、新建数据库: 5、导入数据库 之后点击运行: 出现以下界面说明数据库导入成功: 6、浏览器中新建一个页面访问localhost/test 如果没有出现以下界面可输入:localhost/test/view/login.html 出现以下界面即可:
3.2、云服务器部署(从购买开始)(选看)
这个云服务部署PHP这个在线考试管理系统,由于之前已经写成了PDF的格式了所以这里就不在写了,如果想在云服务器上部署的可以参考,
4、项目获取(阿里云盘)
由于百度网盘对于普通用户来说下载速度太慢太慢所以就放在了阿里云盘中方便大家提取与下载: 提取码: 7cb3 下载链接:https://www.aliyundrive.com/s/Cx4ndY8SvJ1
如果没有阿里云盘可以点击下方链接立即领取自行下载 下载阿里云盘
|