寫在前面
博客好久沒更新了,最近看了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好,基本上一個功能全面一點,大一點的系統很容易出現各種各樣的漏洞。至於效率方面,我沒實測過,也沒有發言權,當然這只是一家之言,兩種都是優秀的語言,不然也不會這么流行。也歡迎大家提出不同的觀點交流討論。