2026/10/12 23:43:06

学生成绩查询系统毕设实战:PHP+MySQL工程化开发指南

学生成绩查询系统毕设实战:PHP+MySQL工程化开发指南 简介这是一套基于PHPMySQL开发的学生成绩查询系统毕业设计源码与配套文档面向计算机专业本科生及Web开发初学者用于完成课程设计、毕设选题或Web全栈技能实践。资源包含66个文件主体为22个PHP功能脚本涵盖登录、增删改查、管理员与学生双模块、23个.mno配置/逻辑文件多为数据库操作封装、4个HTML页面、2个SQL脚本含建表与初始化数据、2个EXE屏幕录相文件分别演示管理员后台与学生端操作流程以及CSS、图片、说明文档等辅助资源整体压缩包12.3MB。已有307人学习下载内容完整覆盖用户管理、成绩录入、条件查询、信息修改等核心业务附带数据库设计说明、项目摘要总结及详细操作录屏便于理解系统架构、调试逻辑与部署要点是入门级PHPMySQL项目实战的典型参考范例。1. 为什么一个“学生成绩查询系统”能成为毕设高频选题它不是 CRUD 练手而是 Web 工程能力的最小闭环“phpmysql毕设-学生成绩查询系统”这个标题在高校计算机类毕业设计选题池里常年稳居 Top 5。但很多同学拿到后第一反应是“不就是增删改查套个模板两天搞定”——结果在答辩前一周卡死在登录态失效、导出 Excel 乱码、成绩统计 SQL 总少算一人、或者部署到服务器后页面全白。真相是它表面平缓实则暗流密集——它强制你串联起 HTTP 请求生命周期、会话状态管理、SQL 注入防御边界、字符集链路一致性、前端异步交互与后端数据结构对齐、以及最常被忽略的「权限收敛」学生只能看自己教师能看所教班级管理员才可全局操作。这不是练手是用最小技术栈PHP 7.4/8.0 MySQL 5.7/8.0跑通一个真实 Web 应用从开发、测试到上线的完整链路。适合大三下至大四上、已掌握 HTML/CSS/JS 基础、刚学完数据库原理与 PHP 语法、急需一个“能讲清楚每一步为什么这么写”的项目来建立工程直觉的同学。本文不讲“如何下载 XAMPP”而是带你亲手搭一个有登录态校验、带班级维度筛选、支持按学期/课程聚合统计、导出防乱码、且所有 SQL 都经参数化处理的可用系统——代码可直接用于毕设逻辑可向导师清晰复述。2. 环境准备与数据库建模为什么用 MySQL 8.0 而非 5.7以及表结构里的三个反直觉设计2.1 本地环境选择PHP 8.1 MySQL 8.0.33 是当前最稳组合毕设交付阶段最怕环境漂移。XAMPP/MAMP/WAMP 虽方便但版本锁定难Docker 对新手调试不友好。我一般会直接装官方二进制包PHP从 windows.php.net 下载php-8.1.29-Win32-vs16-x64.zipWindows或php-8.1.29-macos-arm64.tar.gzMac M1/M2解压后配置php.ini启用extensionmysqli和extensionpdo_mysqlMySQL从 dev.mysql.com 下载mysql-8.0.33-macos12-arm64.dmgMac或mysql-8.0.33-winx64.zipWin安装时务必勾选 “Add MySQL to PATH”否则后续命令行连不上Web 服务用 PHP 内置服务器php -S localhost:8000 -t public/避免 Apache/Nginx 配置干扰主线逻辑。提示MySQL 8.0 默认启用caching_sha2_password认证插件而旧版 PHP mysqli 扩展可能不兼容。若连接报错Client does not support authentication protocol requested by server需在 MySQL 中执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_password; FLUSH PRIVILEGES;这不是降级安全而是毕设阶段优先保证链路跑通——生产环境必须用原生插件。2.2 数据库建模三张表撑起全部业务但字段设计藏了关键约束系统只需三张表users用户、courses课程、scores成绩。但字段命名和约束不是照着 Excel 表头抄——它决定了后续 SQL 的健壮性。表名字段名类型约束说明usersidBIGINT UNSIGNED PK AI主键自增不用 INT防未来用户超 2147 万usernameVARCHAR(50) UNIQUE NOT NULL唯一索引学号/工号不用邮箱教师无邮箱password_hashCHAR(60) NOT NULL—bcrypt 加密后固定 60 字符不用 VARCHARroleENUM(student,teacher,admin) NOT NULL—角色硬编码不另建 role 表毕设够用class_idVARCHAR(20) NULL—学生所属班级如 CS2021教师留空coursesidTINYINT UNSIGNED PK AI—课程数 255用 TINYINT 节省内存nameVARCHAR(100) NOT NULL—课程名如 数据结构与算法semesterVARCHAR(20) NOT NULL—格式统一为 2023-2024-2学年-学期scoresidBIGINT UNSIGNED PK AI—成绩记录主键user_idBIGINT UNSIGNED NOT NULLFK → users.id外键关联不加 ON DELETE CASCADE防误删用户连带清空成绩course_idTINYINT UNSIGNED NOT NULLFK → courses.id—scoreDECIMAL(5,2) CHECK(score BETWEEN 0 AND 100)—支持小数如 89.5CHECK 约束防脏数据反直觉设计 1users.class_id是 VARCHAR 而非外键班级无独立实体不需班级介绍、班主任等字段且班级编码规则由教务系统约定如 EE2022、MA2023用字符串更灵活。加外键反而要建classes表徒增复杂度。反直觉设计 2scores.score用 DECIMAL(5,2) 而非 FLOAT浮点数存储会导致0.1 0.2 ! 0.3成绩计算如平均分必须精确。DECIMAL 按十进制存储5,2表示最多 5 位数字、2 位小数范围 0~999.99完全覆盖需求。反直觉设计 3courses.semester用 VARCHAR 而非 DATE学期是人为划分如 2023-2024-2非自然日期。用 DATE 类型无法表达跨年学期且排序时ORDER BY semester字符串比DATE更直观2023-2024-1 2023-2024-2。2.3 初始化 SQL一条命令导入基础数据含密码哈希与索引优化将以下 SQL 保存为init.sql用mysql -u root -p init.sql执行-- 创建数据库UTF8MB4 防 emoji 乱码 CREATE DATABASE IF NOT EXISTS student_score DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE student_score; -- 创建 users 表 CREATE TABLE users ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL UNIQUE, password_hash CHAR(60) NOT NULL, role ENUM(student,teacher,admin) NOT NULL, class_id VARCHAR(20) NULL, INDEX idx_role_class (role, class_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 创建 courses 表 CREATE TABLE courses ( id TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, semester VARCHAR(20) NOT NULL, INDEX idx_semester (semester), INDEX idx_name (name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 创建 scores 表 CREATE TABLE scores ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL, course_id TINYINT UNSIGNED NOT NULL, score DECIMAL(5,2) NOT NULL CHECK(score BETWEEN 0 AND 100), FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (course_id) REFERENCES courses(id), INDEX idx_user_course (user_id, course_id), INDEX idx_course_score (course_id, score) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 插入测试用户密码均为 123456bcrypt 哈希后值 INSERT INTO users (username, password_hash, role, class_id) VALUES (2021001, $2y$10$ZzZzZzZzZzZzZzZzZzZzZuZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZ, student, CS2021), (2021002, $2y$10$ZzZzZzZzZzZzZzZzZzZzZuZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZ, student, CS2021), (T001, $2y$10$ZzZzZzZzZzZzZzZzZzZzZuZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZ, teacher, NULL), (admin, $2y$10$ZzZzZzZzZzZzZzZzZzZzZuZzZzZzZzZzZzZzZzZzZzZzZzZzZzZzZ, admin, NULL); -- 插入测试课程 INSERT INTO courses (name, semester) VALUES (高等数学, 2023-2024-1), (数据结构与算法, 2023-2024-1), (大学英语, 2023-2024-2); -- 插入测试成绩学生2021001 修了全部三门课 INSERT INTO scores (user_id, course_id, score) VALUES (1, 1, 85.5), (1, 2, 92.0), (1, 3, 88.0), (2, 1, 76.0), (2, 2, 89.5), (2, 3, 91.0), (3, 1, 95.0), (3, 2, 98.0); -- 教师成绩仅作演示实际不显示逻辑说明所有表指定ENGINEInnoDB确保事务与外键支持CHARSETutf8mb4是硬性要求否则中文插入报错或显示问号INDEX语句显式创建复合索引如idx_role_class加速角色班级联合查询教师查所教班级学生成绩密码哈希值$2y$10$...是password_hash(123456, PASSWORD_DEFAULT)生成的 bcrypt 结果切勿明文存密码测试数据覆盖学生、教师、管理员三角色且scores表中教师成绩存在但前端不展示——为权限控制埋点。3. 核心功能实现登录态管理、成绩查询、统计报表三块代码怎么写才不翻车3.1 登录与会话管理为什么 session_start() 必须放在最开头且不能有任何输出PHP 的 session 机制依赖 HTTP 响应头Set-Cookie一旦有空格、BOM 或 echo 输出头就已发送session 将失效。这是毕设答辩现场最高频翻车点。login.php完整代码含防暴力破解基础?php // login.php - 严格前置无空格、无 BOM、无 echo session_start(); require_once config/database.php; // 数据库连接 // 若已登录跳转首页 if (isset($_SESSION[user_id])) { header(Location: index.php); exit; } $error ; if ($_SERVER[REQUEST_METHOD] POST) { $username trim($_POST[username] ?? ); $password $_POST[password] ?? ; // 基础校验防空提交 if (empty($username) || empty($password)) { $error 用户名和密码不能为空; } else { // 预编译查询防 SQL 注入 $stmt $pdo-prepare(SELECT id, username, password_hash, role, class_id FROM users WHERE username ?); $stmt-execute([$username]); $user $stmt-fetch(PDO::FETCH_ASSOC); if ($user password_verify($password, $user[password_hash])) { // 登录成功重置失败计数设置 session $_SESSION[user_id] $user[id]; $_SESSION[username] $user[username]; $_SESSION[role] $user[role]; $_SESSION[class_id] $user[class_id] ?? null; $_SESSION[login_time] time(); // 记录登录日志可选 error_log(Login success: {$user[username]} ({$user[role]})); header(Location: index.php); exit; } else { $error 用户名或密码错误; // 可扩展记录失败次数5次后锁定15分钟需加 failed_login_count 字段 } } } ? !DOCTYPE html html headtitle学生成绩查询系统 - 登录/title/head body h2用户登录/h2 ?php if ($error): ? div stylecolor:red? htmlspecialchars($error) ?/div ?php endif; ? form methodpost label用户名input typetext nameusername required/labelbr label密码input typepassword namepassword required/labelbr button typesubmit登录/button /form /body /html参数说明与踩坑点session_start()必须在任何输出包括 HTML、空格、BOM之前调用否则报错headers already sentpassword_verify()是 PHP 内置函数自动识别 bcrypt 哈希格式无需手动指定算法htmlspecialchars()对错误信息转义防 XSS即使错误信息来自后端也要防万一$pdo来自database.php其内容为?php // config/database.php $host localhost; $dbname student_score; $username root; $password ; // 你的 MySQL 密码 try { $pdo new PDO(mysql:host$host;dbname$dbname;charsetutf8mb4, $username, $password, [ PDO::ATTR_ERRMODE PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE PDO::FETCH_ASSOC, ]); } catch (PDOException $e) { die(数据库连接失败: . $e-getMessage()); }3.2 成绩查询页学生看自己、教师看班级、管理员看全部SQL 如何动态拼接index.php是核心路由页根据角色渲染不同内容。关键在WHERE 条件的动态构建而非写三套 SQL。?php session_start(); require_once config/database.php; // 未登录跳转登录页 if (!isset($_SESSION[user_id])) { header(Location: login.php); exit; } $role $_SESSION[role]; $user_id $_SESSION[user_id]; $class_id $_SESSION[class_id] ?? null; // 构建查询条件安全用预编译参数不拼接字符串 $params []; $where_sql ; switch ($role) { case student: $where_sql s.user_id ?; $params[] $user_id; break; case teacher: // 教师查所教班级所有学生成绩需关联 users 表 $where_sql u.class_id ?; $params[] $class_id; break; case admin: $where_sql 11; // 全部 break; } // 查询成绩 关联课程名 用户名学生/教师名 $sql SELECT s.id, u.username, c.name as course_name, c.semester, s.score FROM scores s JOIN users u ON s.user_id u.id JOIN courses c ON s.course_id c.id WHERE $where_sql ORDER BY u.username, c.semester, c.name; $stmt $pdo-prepare($sql); $stmt-execute($params); $scores $stmt-fetchAll(); ? !DOCTYPE html html headtitle成绩查询/title/head body h2成绩查询? htmlspecialchars($_SESSION[username]) ?/h2 p角色? htmlspecialchars($role) ?/p ?php if (empty($scores)): ? p暂无成绩记录/p ?php else: ? table border1 trth学号/工号/thth课程/thth学期/thth成绩/th/tr ?php foreach ($scores as $row): ? tr td? htmlspecialchars($row[username]) ?/td td? htmlspecialchars($row[course_name]) ?/td td? htmlspecialchars($row[semester]) ?/td td? $row[score] ?/td /tr ?php endforeach; ? /table ?php endif; ? !-- 教师/管理员额外功能导出按钮 -- ?php if ($role teacher || $role admin): ? a hrefexport.php?role? urlencode($role) ?class_id? urlencode($class_id ?? ) ?导出 Excel/a ?php endif; ? /body /html逻辑说明switch动态生成WHERE条件但只生成条件片段参数通过$params数组传入execute()彻底杜绝 SQL 注入JOIN三表关联一次查出所有需要字段避免 N1 查询如循环查每个学生的课程名htmlspecialchars()对所有输出到 HTML 的变量转义双重防护导出链接带role和class_id参数供export.php读取权限上下文。3.3 统计报表用一条 SQL 实现按班级/课程/学期的多维聚合学生只想看自己但教师需知道“本班高等数学平均分多少”管理员要看“2023-2024-1 学期各科及格率”。这些不能靠 PHP 循环计算——要交给 MySQL 的GROUP BY和聚合函数。report.php提供三个统计入口?php session_start(); require_once config/database.php; if (!isset($_SESSION[user_id])) { header(Location: login.php); exit; } $role $_SESSION[role]; $class_id $_SESSION[class_id] ?? null; // 按班级统计教师/管理员可用 $stats_by_class []; if ($role teacher || $role admin) { $sql_class SELECT u.class_id, COUNT(*) as total_students, AVG(s.score) as avg_score, COUNT(CASE WHEN s.score 60 THEN 1 END) * 100.0 / COUNT(*) as pass_rate FROM scores s JOIN users u ON s.user_id u.id WHERE u.class_id IS NOT NULL ; $params_class []; if ($role teacher) { $sql_class . AND u.class_id ?; $params_class[] $class_id; } $sql_class . GROUP BY u.class_id ORDER BY u.class_id; $stmt $pdo-prepare($sql_class); $stmt-execute($params_class); $stats_by_class $stmt-fetchAll(); } // 按课程统计全部角色可用但学生只能看到自己修的课 $stats_by_course []; $sql_course SELECT c.name as course_name, c.semester, COUNT(*) as total_students, AVG(s.score) as avg_score, MIN(s.score) as min_score, MAX(s.score) as max_score FROM scores s JOIN courses c ON s.course_id c.id WHERE 11 ; $params_course []; if ($role student) { $sql_course . AND s.user_id ?; $params_course[] $_SESSION[user_id]; } elseif ($role teacher) { $sql_course . AND s.user_id IN (SELECT id FROM users WHERE class_id ?); $params_course[] $class_id; } $sql_course . GROUP BY c.id, c.name, c.semester ORDER BY c.semester, c.name; $stmt $pdo-prepare($sql_course); $stmt-execute($params_course); $stats_by_course $stmt-fetchAll(); ? !DOCTYPE html html headtitle统计报表/title/head body h2统计报表/h2 ?php if (!empty($stats_by_class)): ? h3按班级统计/h3 table border1 trth班级/thth总人数/thth平均分/thth及格率(%)/th/tr ?php foreach ($stats_by_class as $row): ? tr td? htmlspecialchars($row[class_id]) ?/td td? (int)$row[total_students] ?/td td? number_format($row[avg_score], 2) ?/td td? number_format($row[pass_rate], 2) ?/td /tr ?php endforeach; ? /table ?php endif; ? h3按课程统计/h3 table border1 trth课程/thth学期/thth总人数/thth平均分/thth最低分/thth最高分/th/tr ?php foreach ($stats_by_course as $row): ? tr td? htmlspecialchars($row[course_name]) ?/td td? htmlspecialchars($row[semester]) ?/td td? (int)$row[total_students] ?/td td? number_format($row[avg_score], 2) ?/td td? (float)$row[min_score] ?/td td? (float)$row[max_score] ?/td /tr ?php endforeach; ? /table /body /html关键技巧COUNT(CASE WHEN ... THEN 1 END)是计算条件计数的标准写法比SUM(IF(...))更通用number_format($val, 2)确保小数点后两位显示如85.00避免85显得不专业学生查课程统计时WHERE s.user_id ?保证只统计自己成绩但聚合结果如“本课平均分”仍需全量计算——所以此处逻辑是学生只能看到自己参与的课程统计但统计值基于全班数据符合教学场景。4. 避坑指南毕设答辩前夜最常爆发的 5 个血泪问题与当场修复方案4.1 现象登录后刷新页面session 丢失又跳回登录页原因最常见session_start()前有空格、BOM 或echo次常见PHP 配置session.save_path目录不可写Linux 下/var/lib/php/sessions权限不足隐蔽原因浏览器禁用了 Cookie或隐私模式导致PHPSESSID无法存储。解决用 VS Code 打开所有 PHP 文件右下角确认编码为UTF-8无 BOM在login.php开头加诊断代码?php session_start(); var_dump($_SESSION); // 查看 session 是否写入 echo Session ID: . session_id(); // 查看是否生成 ID exit;若输出为空数组且 ID 为空则是session_start()失败Linux 下执行sudo chmod 1733 /var/lib/php/sessions宽松权限毕设阶段够用浏览器访问chrome://settings/cookies确认localhost未被阻止。4.2 现象中文显示为问号????或 MySQL 报错Incorrect string value原因数据库、表、字段未统一设为utf8mb4PHP 连接 MySQL 时未指定字符集HTML 页面未声明meta charsetUTF-8。解决执行SHOW CREATE DATABASE student_score;确认DEFAULT CHARSETutf8mb4检查config/database.php中 DSN 是否含charsetutf8mb4必须有在所有 HTMLhead中加入meta charsetUTF-8若已有乱码数据不要用ALTER TABLE CONVERT TO会损坏数据而应-- 步骤1修改表字符集不改数据 ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 步骤2逐字段修正安全 ALTER TABLE users MODIFY username VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;4.3 现象导出 Excel 时中文乱码或文件打不开原因export.php输出 CSV 时未加 UTF-8 BOM 头Excel 默认用 ANSI 解析使用了fputcsv()但未处理字段中的逗号、换行符HTTP 响应头缺失Content-Type或Content-Disposition。解决export.php完整方案?php session_start(); require_once config/database.php; if (!isset($_SESSION[user_id])) { die(未登录); } $role $_SESSION[role]; $class_id $_GET[class_id] ?? null; // 构建查询同 index.php 的逻辑 $where_sql ; $params []; if ($role student) { $where_sql s.user_id ?; $params[] $_SESSION[user_id]; } elseif ($role teacher) { $where_sql u.class_id ?; $params[] $class_id; } $sql SELECT u.username, c.name as course_name, c.semester, s.score FROM scores s JOIN users u ON s.user_id u.id JOIN courses c ON s.course_id c.id WHERE $where_sql ORDER BY u.username, c.semester; $stmt $pdo-prepare($sql); $stmt-execute($params); $data $stmt-fetchAll(); // 设置响应头关键 header(Content-Type: text/csv; charsetutf-8); header(Content-Disposition: attachment; filenamescores_export_ . date(Ymd_His) . .csv); // 输出 UTF-8 BOMExcel 识别 UTF-8 的唯一可靠方式 echo \xEF\xBB\xBF; // 输出 CSV 头 $f fopen(php://output, w); fputcsv($f, [学号, 课程, 学期, 成绩]); // 输出数据fputcsv 自动处理转义 foreach ($data as $row) { fputcsv($f, [ $row[username], $row[course_name], $row[semester], $row[score] ]); } fclose($f); exit;4.4 现象教师登录后查不到班级成绩但数据库里明明有数据原因users.class_id字段为NULL但教师账号的class_id未设置初始化 SQL 里T001的class_id是NULL查询时WHERE u.class_id ?而NULL NULL返回falseSQL 三值逻辑教师账号在users表中roleteacher但class_id为空导致WHERE u.class_id ?永远不成立。解决确认教师账号的class_id已设置如UPDATE users SET class_idCS2021 WHERE usernameT001;在index.php的查询逻辑中教师角色应查u.class_id ?但需确保该值非空更健壮写法在教师登录后检查$_SESSION[class_id]是否为空为空则跳转提示“请管理员分配任教班级”。4.5 现象部署到学校服务器后页面全白无任何错误提示原因服务器 PHP 版本过低如 5.6不支持password_hash()或??空合并操作符display_errors关闭错误被静默吞掉error_log路径不可写日志无法生成。解决快速定位在index.php开头加?php ini_set(display_errors, 1); ini_set(display_startup_errors, 1); error_reporting(E_ALL); // ... rest of code创建phpinfo.php?php phpinfo(); ?访问查看PHP Version、Loaded Configuration File确认php.ini路径、error_log设置检查php.ini中error_log指向的文件路径是否可写如/var/log/php_errors.log并chmod 644若版本低于 7.0必须升级 PHP——password_hash()在 5.5 有但??是 7.0 特性毕设系统建议最低 PHP 7.4。5. 进阶技巧让毕设答辩加分的 3 个轻量级但高价值改造5.1 给成绩添加“等级”字段用 MySQL 的CASE WHEN实现前端零计算导师常问“如果要显示‘优/良/中/及格/不及格’怎么设计”——答案不是在 PHP 里if-else而是让数据库返回计算好的等级。修改index.php的查询 SQLSELECT s.id, u.username, c.name as course_name, c.semester, s.score, CASE WHEN s.score 90 THEN 优 WHEN s.score 80 THEN 良 WHEN s.score 70 THEN 中 WHEN s.score 60 THEN 及格 ELSE 不及格 END as grade FROM scores s JOIN users u ON s.user_id u.id JOIN courses c ON s.course_id c.id WHERE $where_sql ORDER BY u.username, c.semester, c.name前端表格增加一列tr th学号/工号/th th课程/th th学期/th th成绩/th th等级/th !-- 新增 -- /tr ?php foreach ($scores as $row): ? tr td? htmlspecialchars($row[username]) ?/td td? htmlspecialchars($row[course_name]) ?/td td? htmlspecialchars($row[semester]) ?/td td? $row[score] ?/td td? htmlspecialchars($row[grade]) ?/td !-- 直接输出 -- /tr ?php endforeach; ?优势等级逻辑在数据库层PHP 只做展示降低耦合修改等级标准只需改 SQL无需动 PHP 代码符合“业务逻辑下沉”原则答辩时可强调“减少应用层计算提升可维护性”。5.2 用.htaccess实现 URL 伪静态把index.php?pagereport变成/report虽然毕设不强制但 URL 干净能体现工程素养。Apache 服务器下根目录新建.htaccess# 启用重写引擎 RewriteEngine On # 防止直接访问 .php 文件可选安全加固 Files *.php Order Deny,Allow Deny from all /Files # 伪静态规则 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^login$ login.php [L] RewriteRule ^logout$ logout.php [L] RewriteRule ^report$ report.php [L] RewriteRule ^export$ export.php [L] RewriteRule ^(.*)$ index.php [L]配套修改所有href改为a href/report统计报表/aindex.php本文还有配套的精品资源点击获取