生成績查詢系統(tǒng)開發(fā)實(shí)戰(zhàn):源碼、論文與避坑指南)
簡介面向PHP初學(xué)者與畢業(yè)設(shè)計(jì)開發(fā)者這份源代碼包提供一個(gè)完整的學(xué)生成績查詢系統(tǒng)方案采用PHPMySQL實(shí)現(xiàn)覆蓋用戶登錄與權(quán)限控制、成績錄入修改、按學(xué)號(hào)/姓名/課程查詢、成績統(tǒng)計(jì)分析以及SQL注入防護(hù)等模塊可應(yīng)用于教育機(jī)構(gòu)或課程設(shè)計(jì)參考。壓縮包共66個(gè)文件大小約12.1MB以php源碼和mno模板文件為主另含htm頁面、css樣式、jpg/gif/png圖片、sql數(shù)據(jù)庫腳本、exe操作錄屏以及doc/docx論文文檔結(jié)構(gòu)覆蓋從代碼到文檔的完整交付內(nèi)容。其中的論文文檔闡述系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)思路測試說明文檔提供驗(yàn)證信息操作錄屏可直觀演示學(xué)生模塊和數(shù)據(jù)庫設(shè)計(jì)過程便于邊看邊練。已有1000人學(xué)習(xí)下載目錄劃分清晰適合作為畢業(yè)設(shè)計(jì)、課設(shè)作業(yè)或PHPMySQL項(xiàng)目實(shí)戰(zhàn)的參考藍(lán)本。1. phpmysql學(xué)生成績查詢系統(tǒng)這份壓縮包的含金量在哪拿到標(biāo)題為「phpmysql學(xué)生成績查詢系統(tǒng)(源代碼論文).zip」的壓縮包很多人的第一反應(yīng)是解壓、點(diǎn)開、跑不起來然后默默關(guān)掉。其實(shí)這類項(xiàng)目是所有做課程設(shè)計(jì)和畢業(yè)設(shè)計(jì)的人都繞不開的入場券——一個(gè)學(xué)生登錄后查成績、老師錄入修改成績、管理員管理賬號(hào)的最小閉環(huán)系統(tǒng)。這套系統(tǒng)的價(jià)值不在代碼量而在于它同時(shí)給了你兩條線一是能直接演示的 PHPMySQL 業(yè)務(wù)邏輯二是配套的論文文檔。對(duì)剛?cè)腴T的人來說讀源碼比讀教材快跑起來比看截圖有用對(duì)要交作業(yè)的人來說把源碼和論文對(duì)照著改比從零寫省數(shù)周時(shí)間。很多老手的第一份 Web 開發(fā)工作就是從改這類系統(tǒng)起步的。下面按我做這類小系統(tǒng)的習(xí)慣講清楚三件事系統(tǒng)怎么拆、本地怎么跑通、踩坑怎么定位。文中的 SQL 和 PHP 代碼都可以直接復(fù)制修改后使用適合已經(jīng)搭過 Apache 和 MySQL、但沒寫過完整業(yè)務(wù)代碼的人。2. 成績查詢系統(tǒng)的需求拆解角色、流程與數(shù)據(jù)模型2.1 三種角色和兩條核心業(yè)務(wù)流學(xué)生成績查詢系統(tǒng)的業(yè)務(wù)邊界其實(shí)很窄。我一般會(huì)先劃角色再列流程學(xué)生負(fù)責(zé)登錄和查成績老師負(fù)責(zé)錄入和修改成績管理員負(fù)責(zé)維護(hù)學(xué)生、課程和賬號(hào)信息。三個(gè)角色不共用同一個(gè)操作界面而是各自登錄后進(jìn)入不同的頁面這一點(diǎn)在論文的用例圖里也是按角色分開畫的。角色登錄入口核心操作學(xué)生學(xué)生登錄頁查詢成績、查看學(xué)分加權(quán)平均分老師教師登錄頁按課程錄入成績、修改成績管理員管理登錄頁維護(hù)學(xué)生和課程數(shù)據(jù)、重置密碼兩條核心業(yè)務(wù)流分別是學(xué)生登錄后按學(xué)期或課程查詢成績系統(tǒng)返回分?jǐn)?shù)、學(xué)分并計(jì)算平均分老師登錄后選擇課程、輸入學(xué)號(hào)和分?jǐn)?shù)系統(tǒng)寫入成績表并立即更新該課程的成績列表。設(shè)計(jì)這類系統(tǒng)時(shí)最常見的錯(cuò)誤是角色越加越多把選課、排課、考勤全塞進(jìn)來導(dǎo)致業(yè)務(wù)流混亂、頁面數(shù)量失控。作為課程設(shè)計(jì)保持「錄」和「查」兩條主線就夠了多出來的功能如果確實(shí)想做放到論文的「系統(tǒng)擴(kuò)展」一節(jié)去寫比在代碼里硬做更討巧。2.2 學(xué)生、課程、成績?nèi)龔埍淼脑O(shè)計(jì)細(xì)節(jié)數(shù)據(jù)庫是整個(gè)系統(tǒng)里最先決定成敗的部分。我慣用的做法是四張表student、course、score 三張業(yè)務(wù)表外加一張 manager 表給老師和管理員共用。student 表的主鍵就用學(xué)號(hào)字符串course 表的主鍵用課程編號(hào)score 表則用自增 id 做主鍵再把 student_id 和 course_id 作為外鍵關(guān)聯(lián)另外兩張表。score 表是核心一個(gè)學(xué)生同一門課程在同一學(xué)期只能有一條成績記錄所以要把 (student_id, course_id, semester) 設(shè)成聯(lián)合唯一鍵否則老師重復(fù)錄一次成績數(shù)據(jù)就會(huì)悄無聲息地翻倍。成績字段我用 DECIMAL(5,1)范圍足夠覆蓋 0 到 100 分帶一位小數(shù)比 INT 更適合真實(shí)成績。課程表里的 credit 學(xué)分字段也不要用 INT很多課程學(xué)分是 1.5 或 2.5DECIMAL(3,1) 才放得下。初始化數(shù)據(jù)同樣值得花十分鐘準(zhǔn)備。每個(gè)角色至少插兩條測試數(shù)據(jù)學(xué)生表里放一個(gè)有多門課程成績的學(xué)生方便演示平均分計(jì)算再放一個(gè)完全沒有成績的學(xué)生用來演示「未出分」和「空列表」這兩個(gè)邊界場景。答辯時(shí)老師大概率會(huì)挑一個(gè)查不到成績的賬號(hào)讓現(xiàn)場演示沒有準(zhǔn)備就是當(dāng)場翻車。2.3 論文目錄怎么跟著功能走一份合格的配套論文核心思路是把功能模塊翻譯成章節(jié)標(biāo)題。我見過不少同學(xué)把論文寫成軟件工程教科書的目錄復(fù)讀機(jī)前三章全是理論第四章才開始講系統(tǒng)論文六十頁真正的設(shè)計(jì)內(nèi)容只有十頁。老師翻一眼就知道哪些是湊出來的。正確節(jié)奏是第二章寫需求分析第三章寫總體設(shè)計(jì)包括系統(tǒng)架構(gòu)、數(shù)據(jù)庫 E-R 圖和表結(jié)構(gòu)第四章寫詳細(xì)設(shè)計(jì)與實(shí)現(xiàn)每個(gè)模塊配頁面截圖和關(guān)鍵代碼第五章寫測試。測試部分不要只寫一句「系統(tǒng)運(yùn)行正?!怪辽倭谐龅卿?、查詢、錄入、越權(quán)訪問四條測試用例每條給出輸入、預(yù)期輸出和實(shí)際結(jié)果。論文的參考文獻(xiàn)部分建議放兩本 PHP 入門書和兩篇關(guān)于 Web 安全的文章這樣答辯時(shí)被問到「SQL 注入怎么防」時(shí)可以直接指到論文里的引用出處說明自己做過功課。參考文獻(xiàn)寧可少不要編老師會(huì)抽查。3. 本地跑通最小系統(tǒng)環(huán)境、建庫與核心代碼3.1 搭一個(gè)能跑 PHP 的本地環(huán)境運(yùn)行 PHPMySQL 系統(tǒng)最常見的方式是在本機(jī)安裝一套集成環(huán)境一次性獲得 Apache、PHP 和 MySQL 三個(gè)組件。裝好之后把項(xiàng)目文件夾放到集成環(huán)境的 Web 根目錄下訪問 http://127.0.0.1/項(xiàng)目名 就能打開入口頁面。這里有個(gè)新手容易卡住的細(xì)節(jié)集成環(huán)境默認(rèn)的 MySQL 端口是 3306如果機(jī)器之前單獨(dú)裝過 MySQL端口被占用集成環(huán)境的數(shù)據(jù)庫服務(wù)就起不來。處理辦法是停掉其中一個(gè)或者改掉集成環(huán)境的端口號(hào)但項(xiàng)目配置文件里的 DB_PORT 必須跟著改。環(huán)境就緒后先用瀏覽器打開自帶的數(shù)據(jù)庫管理工具確認(rèn)能正常登錄數(shù)據(jù)庫再進(jìn)入下一步。我習(xí)慣把數(shù)據(jù)庫地址、用戶名、密碼統(tǒng)一寫在項(xiàng)目根目錄的 config.php 里。這樣后期部署到服務(wù)器只改一個(gè)文件不用滿項(xiàng)目搜索數(shù)據(jù)庫連接字符串。壓縮包里的源碼如果連接配置寫得散第一件事就是把它們收斂到一個(gè)文件里。3.2 建庫建表 SQL最小可用版下面這份 SQL 是成績查詢系統(tǒng)的最小可用版本。它只建了四張表去掉了頭像、年級(jí)、院系這類裝飾字段目的是先把數(shù)據(jù)模型立住。-- init.sql 學(xué)生成績查詢系統(tǒng)數(shù)據(jù)庫初始化腳本 CREATE DATABASE IF NOT EXISTS grade_system DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE grade_system; CREATE TABLE student ( student_id VARCHAR(20) PRIMARY KEY COMMENT 學(xué)號(hào), student_name VARCHAR(50) NOT NULL COMMENT 姓名, class_name VARCHAR(50) DEFAULT NULL COMMENT 班級(jí), password VARCHAR(255) NOT NULL COMMENT 登錄密碼, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 創(chuàng)建時(shí)間 ) ENGINEInnoDB COMMENT學(xué)生表; CREATE TABLE course ( course_id VARCHAR(20) PRIMARY KEY COMMENT 課程編號(hào), course_name VARCHAR(100) NOT NULL COMMENT 課程名稱, credit DECIMAL(3,1) DEFAULT 0 COMMENT 學(xué)分, teacher_id VARCHAR(20) DEFAULT NULL COMMENT 授課教師ID ) ENGINEInnoDB COMMENT課程表; CREATE TABLE score ( id INT AUTO_INCREMENT PRIMARY KEY, student_id VARCHAR(20) NOT NULL COMMENT 學(xué)號(hào), course_id VARCHAR(20) NOT NULL COMMENT 課程編號(hào), semester VARCHAR(20) NOT NULL COMMENT 學(xué)期如 2024-2025-1, score DECIMAL(5,1) DEFAULT NULL COMMENT 成績, UNIQUE KEY uk_student_course_sem (student_id, course_id, semester), CONSTRAINT fk_score_student FOREIGN KEY (student_id) REFERENCES student(student_id), CONSTRAINT fk_score_course FOREIGN KEY (course_id) REFERENCES course(course_id) ) ENGINEInnoDB COMMENT成績表; CREATE TABLE manager ( manager_id VARCHAR(20) PRIMARY KEY COMMENT 教職工號(hào), manager_name VARCHAR(50) NOT NULL COMMENT 姓名, password VARCHAR(255) NOT NULL COMMENT 登錄密碼, role TINYINT NOT NULL DEFAULT 2 COMMENT 1管理員 2老師 ) ENGINEInnoDB COMMENT教師/管理員表;這份腳本里有三個(gè)設(shè)計(jì)選擇值得說明。一是字符集統(tǒng)一用 utf8mb4這是后面避免中文亂碼的基礎(chǔ)。二是 score 表的聯(lián)合唯一鍵保證重復(fù)錄入不產(chǎn)生臟數(shù)據(jù)。三是外鍵約束必須加很多入門項(xiàng)目圖省事不加外鍵刪除學(xué)生后成績表里留下一堆孤兒數(shù)據(jù)論文里寫「數(shù)據(jù)完整性」時(shí)完全站不住腳。導(dǎo)入方法通常有兩種在數(shù)據(jù)庫管理工具里選擇 grade_system 數(shù)據(jù)庫后執(zhí)行整個(gè)腳本或者在命令行執(zhí)行 mysql -u root -p init.sql。執(zhí)行完可以用 SHOW TABLES 確認(rèn)四張表都建出來了再用 SELECT * FROM student; 抽查一條數(shù)據(jù)。3.3 登錄與成績查詢的 PHP 代碼數(shù)據(jù)庫建好后下一步就是寫入口和查詢邏輯。下面是兩個(gè)核心 PHP 文件數(shù)據(jù)庫連接配置和登錄驗(yàn)證。?php // config.php 數(shù)據(jù)庫連接配置 define(DB_HOST, 127.0.0.1); // 連接地址端口被改時(shí)寫成 127.0.0.1:3307 define(DB_USER, root); // 數(shù)據(jù)庫用戶名 define(DB_PASS, root); // 數(shù)據(jù)庫密碼按本地環(huán)境修改 define(DB_NAME, grade_system); function db_connect() { $conn new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME); $conn-set_charset(utf8mb4); // 與建庫字符集保持一致 if ($conn-connect_errno) { error_log(DB connect error: . $conn-connect_error); die(數(shù)據(jù)庫連接失敗請(qǐng)檢查 config.php 配置); } return $conn; } ??php // login.php 學(xué)生登錄驗(yàn)證 session_start(); require config.php; if ($_SERVER[REQUEST_METHOD] POST) { $student_id trim($_POST[student_id] ?? ); $password trim($_POST[password] ?? ); $conn db_connect(); // 預(yù)處理語句防止 SQL 注入 $stmt $conn-prepare( SELECT student_id, student_name FROM student WHERE student_id ? AND password ? ); $stmt-bind_param(ss, $student_id, $password); $stmt-execute(); $result $stmt-get_result(); if ($row $result-fetch_assoc()) { $_SESSION[student_id] $row[student_id]; $_SESSION[student_name] $row[student_name]; header(Location: query_score.php); exit; } $error 學(xué)號(hào)或密碼錯(cuò)誤; $stmt-close(); $conn-close(); } ?登錄邏輯的核心在 bind_param 這一行。兩個(gè) s 代表兩個(gè)字符串參數(shù)? 占位符會(huì)被安全地替換為變量值而不是直接拼進(jìn) SQL 語句。這是防御 SQL 注入的最低要求也是答辯時(shí)老師最常檢查的一行代碼。這里保留的是課程設(shè)計(jì)里最常見的明文密碼寫法更安全的 password_hash 方案在 4.3 節(jié)展開講。成績查詢頁的代碼稍長一些因?yàn)樗幚砜蛇x的學(xué)期過濾參數(shù)還要計(jì)算學(xué)分加權(quán)平均分。?php // query_score.php 成績查詢與平均分計(jì)算 session_start(); if (!isset($_SESSION[student_id])) { header(Location: login.php); exit; } require config.php; $conn db_connect(); $student_id $_SESSION[student_id]; $semester trim($_GET[semester] ?? ); // 可選按學(xué)期過濾 $sql SELECT c.course_name, c.credit, s.score, s.semester FROM score s JOIN course c ON s.course_id c.course_id WHERE s.student_id ?; $params [$student_id]; $types s; if ($semester ! ) { $sql . AND s.semester ?; $params[] $semester; $types . s; } $sql . ORDER BY s.semester DESC, c.course_id ASC; $stmt $conn-prepare($sql); $stmt-bind_param($types, ...$params); $stmt-execute(); $result $stmt-get_result(); $rows []; $total_credit 0; $weighted_score 0; while ($row $result-fetch_assoc()) { $rows[] $row; $total_credit $row[credit]; $weighted_score $row[credit] * $row[score]; } $avg $total_credit 0 ? round($weighted_score / $total_credit, 2) : 0; $conn-close(); ?這段代碼里有兩個(gè)關(guān)鍵點(diǎn)。一是 JOIN 把 score 表和 course 表連起來查這樣前端的表格可以直接顯示課程名稱而不是只顯示課程編號(hào)少一次連表查詢代碼也干凈。二是 bind_param 的類型字符串要和參數(shù)數(shù)量嚴(yán)格對(duì)應(yīng)條件分支里往 $types 追加字符時(shí)寫漏了PHP 會(huì)直接拋出參數(shù)數(shù)量不匹配的致命錯(cuò)誤這是動(dòng)態(tài)拼接查詢條件時(shí)最容易踩的坑。HTML 展示層我只寫一個(gè)簡單的表格循環(huán)成績?yōu)?NULL 的課程顯示「未出分」而不是顯示 0。補(bǔ)考和緩考的出分時(shí)間晚這個(gè)細(xì)節(jié)在演示時(shí)很容易被老師注意到屬于低成本高回報(bào)的小優(yōu)化。3.4 論文寫作把源碼翻譯成文檔配套論文的寫作順序和寫代碼順序是反的。先搭好目錄框架然后每完成一個(gè)模塊立刻截圖并補(bǔ)一段實(shí)現(xiàn)說明。我常用一種「功能、流程、代碼、測試」四段式寫每個(gè)模塊功能段講這個(gè)頁面解決什么問題流程段用文字描述用戶從進(jìn)入頁面到離開的完整操作路徑代碼段貼關(guān)鍵代碼并解釋核心邏輯不用全文粘貼測試段寫該模塊的測試用例和結(jié)果。四段式寫下來每個(gè)模塊大約一千五百字四個(gè)模塊就是六千字加上需求分析和總體設(shè)計(jì)論文正文輕松達(dá)到課程設(shè)計(jì)的篇幅要求而且每一頁都是真實(shí)內(nèi)容。答辯時(shí)老師常問的三個(gè)問題——表為什么這么設(shè)計(jì)、SQL 注入怎么防、成績修改記錄怎么追蹤——前兩個(gè)在 2.2 和 3.3 節(jié)里都有對(duì)應(yīng)答案。第三個(gè)建議在 score 表上加一個(gè) updated_at 字段錄入成績時(shí)把修改時(shí)間一并寫入。雖然很多課程設(shè)計(jì)不做這個(gè)一旦做了在答辯現(xiàn)場就是亮點(diǎn)。遇到「如何追蹤成績被誰改過」這種壓力提問至少能給出一個(gè)明確的實(shí)現(xiàn)方向。4. 排查避坑成績查詢系統(tǒng)最常見的五個(gè)問題4.1 數(shù)據(jù)庫連接失敗先看端口再看權(quán)限現(xiàn)象打開頁面直接顯示「數(shù)據(jù)庫連接失敗」PHP 錯(cuò)誤日志里是 Access denied 或 Connection refused。排查按三步走。第一步確認(rèn) MySQL 服務(wù)真的在運(yùn)行去集成環(huán)境自帶的服務(wù)面板看狀態(tài)第二步確認(rèn)端口改了端口的話 config.php 里的 DB_HOST 要寫成 127.0.0.1:新端口第三步確認(rèn)用戶名密碼集成環(huán)境的 MySQL root 密碼常常是 root 或空密碼和自己單獨(dú)安裝 MySQL 時(shí)設(shè)置的口令不一定一致。解決方法是把 config.php 里的 DB_PASS 改成實(shí)際密碼。如果仍然失敗在命令行手動(dòng)執(zhí)行 mysql -u root -p 連接一次能連上說明是 PHP 側(cè)配置問題連不上說明是權(quán)限問題。權(quán)限問題在 MySQL 里執(zhí)行 ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 新密碼; 然后刷新權(quán)限即可。4.2 中文亂碼問題出在字符集鏈路現(xiàn)象頁面標(biāo)題和按鈕正常但查詢出來的課程名稱、學(xué)生姓名變成問號(hào)或者亂碼。原因亂碼從來不是單個(gè)文件的問題而是數(shù)據(jù)庫字符集、PHP 連接字符集、HTML 頁面編碼三個(gè)環(huán)節(jié)不一致。數(shù)據(jù)庫是 utf8、PHP 連接用 utf8mb4、HTML 聲明的是 GBK三個(gè)編碼互相打架亂碼必現(xiàn)。解決把三處統(tǒng)一到 utf8mb4。建庫腳本里指定 DEFAULT CHARACTER SET utf8mb4PHP 連接后執(zhí)行 set_charset(utf8mb4)HTML 的 head 里加 。如果表已經(jīng)建好還需要單獨(dú)轉(zhuǎn)換ALTER TABLE student CONVERT TO CHARACTER SET utf8mb4; 只改庫不改表同樣救不回來。4.3 登錄繞過與 SQL 注入最容易被扣分的點(diǎn)現(xiàn)象在學(xué)號(hào)輸入框填入 or 11密碼隨便填結(jié)果直接跳進(jìn)了成績查詢頁面甚至能看到所有人的成績。原因登錄 SQL 是字符串拼接出來的形如 SELECT * FROM student WHERE student_id $id AND password $pwd。單引號(hào)沒有轉(zhuǎn)義導(dǎo)致條件恒真整條查詢返回第一行數(shù)據(jù)登錄驗(yàn)證形同虛設(shè)。解決把拼接改成預(yù)處理語句用 bind_param 傳入?yún)?shù)值3.3 節(jié)的 login.php 已經(jīng)是標(biāo)準(zhǔn)寫法。在此基礎(chǔ)上密碼不要明文存儲(chǔ)改用 password_hash() 存儲(chǔ)、password_verify() 驗(yàn)證。這兩件事是成績查詢系統(tǒng)「安全性設(shè)計(jì)」一節(jié)的底線論文里如果沒有寫答辯基本會(huì)被追問到改口。4.4 改了密碼后 Session 異常無痕窗口最好用現(xiàn)象在老師端重置了某學(xué)生的密碼再用學(xué)生賬號(hào)登錄明明密碼正確卻登錄失敗或者登錄成功后立刻被踢回登錄頁。原因分兩種。一種是老師端的改密功能執(zhí)行了 UPDATE但沒有清理舊的 session當(dāng)前會(huì)話里殘留的登錄態(tài)和數(shù)據(jù)庫新值對(duì)不上另一種是多個(gè)項(xiàng)目共用一個(gè) PHP 運(yùn)行環(huán)境session 文件名互相干擾。解決改密碼的代碼里執(zhí)行 UPDATE 后調(diào)用 session_destroy() 或者 session_regenerate_id(true)強(qiáng)制用戶重新登錄。排查 session 問題最省事的方法是開無痕窗口測試排除瀏覽器 cookie 干擾。多項(xiàng)目共用環(huán)境時(shí)在每個(gè)項(xiàng)目入口調(diào)用 session_name(grade_system_sess) 指定唯一會(huì)話名互不覆蓋。4.5 部署后樣式和跳轉(zhuǎn)全崩路徑問題的根源現(xiàn)象本地運(yùn)行一切正常部署到服務(wù)器后頁面沒有樣式登錄跳轉(zhuǎn)到了莫名其妙的位置。原因頁面里 CSS 引用和跳轉(zhuǎn)地址用了絕對(duì)路徑比如 /css/style.css。本地根目錄和服務(wù)器部署的子目錄不一致時(shí)路徑就全部失效。header(Location: query_score.php) 這類跳轉(zhuǎn)在某些目錄結(jié)構(gòu)下也會(huì)跳到錯(cuò)誤位置。解決CSS 引用改用相對(duì)路徑或者用 PHP 動(dòng)態(tài)拼接路徑比如 $base dirname($_SERVER[SCRIPT_NAME])。跳轉(zhuǎn)統(tǒng)一用項(xiàng)目內(nèi)相對(duì)路徑不要帶前導(dǎo)斜杠。這類問題的本質(zhì)是環(huán)境不一致所以我在交付成品時(shí)習(xí)慣附一份部署說明寫清楚根目錄要求、目錄權(quán)限和 config.php 需要改的三處配置能省掉使用者一半的提問。5. 從能跑到能交三個(gè)提升完成度的收尾技巧5.1 給查詢頁加學(xué)期篩選下拉框3.3 節(jié)的查詢代碼已經(jīng)預(yù)留了 $semester 參數(shù)。前端加一個(gè)下拉框選項(xiàng)來自 SELECT DISTINCT semester FROM score WHERE student_id ?提交后帶上學(xué)期參數(shù)重新查詢。這個(gè)功能工作量很小但論文的查詢模塊能因此多兩條測試用例演示時(shí)老師也更容易注意到系統(tǒng)不是寫死的。5.2 一鍵導(dǎo)出成績?yōu)?CSV導(dǎo)出功能是老師端最受歡迎的小功能。實(shí)現(xiàn)很樸素查詢結(jié)果逐行拼成 CSV 文本用 header() 設(shè)置 Content-Type 為 text/csv瀏覽器自動(dòng)下載。注意 CSV 內(nèi)容要加 UTF-8 的 BOM 頭也就是 chr(239).chr(187).chr(191)否則用表格軟件打開中文會(huì)亂碼。5.3 答辯前十分鐘的檢查清單我的習(xí)慣是按「登錄、查詢、異常、部署」四步快速過一遍三個(gè)角色的賬號(hào)各登錄一次查詢有成績、沒成績、學(xué)期過濾三種情況故意輸錯(cuò)密碼一次確認(rèn)錯(cuò)誤提示正常最后確認(rèn) config.php 里是演示環(huán)境的配置。另外記得把 PHP 的 display_errors 關(guān)掉只保留 error_log不然一個(gè) Notice 級(jí)別的警告就能讓頁面頂部出現(xiàn)一整行難看的報(bào)錯(cuò)。在成績查詢系統(tǒng)這個(gè)方向上我見過太多因?yàn)榄h(huán)境問題而不是代碼問題翻車的演示。把環(huán)境當(dāng)作系統(tǒng)的一部分來管理每次部署都按清單過一遍是這門課之外真正能帶走的東西。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取