寫在前面
部落格好久沒更新了,最近看了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好,基本上一個功能全面一點,大一點的系統很容易出現各種各樣的漏洞。至於效率方面,我沒實測過,也沒有發言權,當然這隻是一家之言,兩種都是優秀的語言,不然也不會這麼流行。也歡迎大家提出不同的觀點交流討論。
最後該項目已開源https://code.google.com/p/phpscores/