写在前面
博客好久没更新了,最近看了MSRA牛人刘未鹏的博客(www.mindhacks.cn),深有感触,感觉学习到了很多东西,关于算法学习,思维方法,职业发展等等,因此看了好几篇他的博客之后我就做了两件事
- 将我之前所有项目代码都上传到github上
- 继续坚持写博客
正好这个礼拜受某中学委托用php写了一个成绩管理系统,因此就把系统开发过程记录下来,当做是一个总结,也和各位园友交流一下,共同提高进步。
因为本人目前还只是在校学生,因此知识经验必然存在很大不足,文章内容也难免疏漏粗浅,如有偏颇的地方希望大家多多理解。交流进步才是最终目的,谢谢!
成绩管理系统的角色及功能
- 1. 管理员
1.1 导入用户信息(包括学生和教师)
1.2.1 登记考试(包括全县统考、全校统考、班级考试)
1.2.2 查询考试信息
1.3 导入成绩
1.4 修改密码
1.5 用户查找
- 2. 教师
2.1 查看本班所有学生成绩(包括各科分数、总分、排名)
2.2 修改密码
- 3. 学生
3.1 查看自己的所有考试成绩
3.2 修改密码
具体用的技术
后台语言:Php
前台语言及框架:html+javascript+jquery
部署服务器:linux+nginx
开发过程
- 1. 数据库设计
数据库中有3个表:grades(分数表)、users(用户表)、exams(考试表)
users表中用户ID是Grades表中userid的外键
exams表中考试id是grades中examid的外键
- 2. 登录
登录界面
登录界面是在网上找到的一个用jquery制作的很好看的登录界面,这里提供下下载地址:
http://www.veryhuo.com/down/html/55826.html
登录逻辑
如果用户登录成功读取用户的用户类型(管理员,教师,学生),当然为了避免sql诸如,将用户输入都做了特殊字符过滤处理,并将用户的用户名、用户类型、用户ID等信息读入$_session中,然后分别导向不同的页面(admin.php、teacher.php、student.php),在这些页面里也对session重新进行验证,避免未授权用户直接访问该页面。用户点击退出后就把session里的一些变量置空。
- 3. 用户界面
管理员导入用户信息和成绩信息都用php-reader这款第三方插件来读取上传的excel信息,这里也提供这款插件下载地址:http://code.google.com/p/php-reader/
这款插件提供了一些很方便的方法来获取excel文件的数据,甚至可以读取一些如单元格边框颜色等附加信息,但是要注意的是这款插件只能读取.xls文件,不能读取.xlxs文件。
其他教师和学生界面的功能都只是简单的查表返回结果,没有什么复杂的功能。
一些具体的功能也到细节实现中去细说吧。下面上一张用户操作的界面图
- 4. 使用逻辑
- 管理员导入用户信息(包括学生和教师)
- 管理员登记考试信息,系统获取考试ID并返回给管理员(为了区分导入grades表的成绩数据需要给每次考试分配一个ID )
- 管理员导入成绩表(有一列是第二步获取的考试ID)
- 教师和学生登录查询成绩
(关于考试管理这里之所以要让管理员获取一个考试ID是因为我担心管理员录入考试成绩的时候有漏录的情况,为了让系统知道后面补录的成绩是前一次录的这次成绩,就需要一个考试ID来把他们联系起来,因此引入了这个获取考试ID的看似冗杂的步骤)
一些细节实现
- 1. 教师界面查询本班所有学生成绩
因为我将所有学生成绩都放在同一张表grades里,而这张表里每条记录都是一个学生某次考试的记录,因此要将这个老师班上学生有关的考试的成绩都查询出来并且每次考试按照名次排序,因此必然涉及到多表查询的问题,而因为成绩字段比较多,也造就了我有史以来最长的SQL($exam_id是之前查询出来的该教师班级所有学生参与的考试ID号):
SELECT t1.sx,t1.yw,t1.yy,t1.wl,t1.hx,t1.sw,t1.ls,t1.zz,t1.dl, (coalesce(t1.sx,0)+coalesce(t1.yw,0)+coalesce(t1.yy,0)+coalesce(wl,0) +coalesce(hx,0)+coalesce(sw,0)+coalesce(ls,0)+coalesce(dl,0)+coalesce(zz,0)) as sumscore,t2.realname FROM myphpcj.grades as t1 ,users as t2 where t1.userid=t2.id and exam_id=".$exam_id." order by sumscore desc";
看起来可能有点长,这里大致解释一下,t1是grades表,t2是用户表。两表联合查询得出该次考试每个学生姓名,学号,分数,总分,最后按总分排序,因为有的科目学生未参加或者本次考试不包含,因此采用了mysql的coalesce函数来处理null值。之前很少用联合表查询,这次试用之后发现可以简化很多程序逻辑,提高程序效率。这次数据库设计的时候使用了一些外键,可以说对于简化程序异常处理也起了很大作用。总之感觉对数据库开发也有了更深的理解。
- 2. 文件保存避免重名
因为要导入用户成绩,我想法是先把文件上传到files目录下,然后再读取文件内容导入信息。我想将所有文件用日期时间戳来命名,这就涉及同一天上传多次文件覆盖的问题,最后想了一个办法同一天上传的文件后面加上上传顺序1,2,3….. 。同时如果中间删了一个文件,后面上传的文件会填补这个数字位置。于是在上传代码里加了如下处理:
$i=1; $save_filename="files/users".date("Y-m-d[").$i."].xls"; while(file_exists("files/users".date("Y-m-d[").$i."].xls")) { $i=$i+1; $save_filename="files/users".date("Y-m-d[").$i."].xls"; } move_uploaded_file($_FILES["grade_file"]["tmp_name"], $save_filename);
最后效果是这样的:
其他一些功能也比较简单,这里就不细说了。至于安全方面,因为没有什么相关的经验,只是在所有表单基本都做了特殊字符过滤避免SQL注入,用户登录也做了登录失败次数记录防止蛮力破解。至于XSS,网站不提供对外注册,封闭性较强就也没怎么考虑。
写在最后
之前一直用.net 开发web,这次在w3school上看了两天php的教程(这里要赞一下这个网站,不清楚的同学可以百度一下,教程内容精简不失重点!)之后就上手花了3天做这个东西,最后虽然功能比较简单,界面效果也一般,但是自己还是比较满意的,一方面增加了一种技能,另一方面也对这两种技术做了个简单的对比,个人认为php跟html和js的结合较好,因此做前端相对轻松一些,而且开发效率个人感觉也较.net高一些,但是毕竟是脚本语言,安全性肯定没.net好,基本上一个功能全面一点,大一点的系统很容易出现各种各样的漏洞。至于效率方面,我没实测过,也没有发言权,当然这只是一家之言,两种都是优秀的语言,不然也不会这么流行。也欢迎大家提出不同的观点交流讨论。