
本文还有配套的精品资源点击获取简介纯原生PHP写的学生成绩管理程序不依赖Laravel、ThinkPHP等任何框架也不用Composer、路由或模板引擎只靠基础PHPMySQLHTMLCSSJS就能跑起来。系统分学生和教师两个入口学生登录后能看自己各科成绩、改密码和基本信息教师登录后可以增删改查学生档案、批量录成绩、单条修改分数、重置学生密码。所有PHP文件都是手写逻辑比如add_student_submit.php处理新增学生update_mark_submit.php更新分数check_session_login.php做登录校验代码带中文注释结构一目了然。压缩包里有全部前端页面index.html、style.css、swiper.min.css等、后端PHP脚本共20多个核心文件、建库建表的SQL文件直接phpMyAdmin导入就行、Word版图文说明文档、项目结构图还有一个实操演示视频php学生管理系统.mov从环境部署到功能操作全涵盖。适合PHP初学者练手、课程设计参考或快速搭建轻量教学管理后台。1. 为什么“零框架”才是新手学PHP的黄金起点刚接触PHP的新手常被Laravel的Artisan命令、ThinkPHP的路由定义、Composer的依赖管理绕得晕头转向。我带过十几届学生做课程设计发现一个铁律90%的人卡在“环境配不起来”和“不知道哪段代码管哪个功能”上而不是逻辑本身。这套“零框架PHP学生成绩系统”就是我用三年时间打磨出来的“去幻觉教学工具”——它不炫技不堆砌概念只用最原始的?php ?标签、$_POST接收、mysqli_query()执行SQL把Web开发最底层的“请求-处理-响应”链条像拆解自行车一样摊开给你看。核心关键词“原生PHP”在这里不是怀旧而是精准的教学策略。比如学生登录后查看成绩整个流程只有三步index.php表单提交 →check_session_login.php验证账号密码并启动session →stuinfo.php从数据库查出该学生所有科目成绩并渲染HTML表格。没有中间件拦截、没有路由映射、没有自动注入你打开任何一个PHP文件第一行就能看到?php session_start();最后一行就是/body闭合标签。这种“所见即所得”的结构让初学者第一次真正理解“为什么改了query.php里的SQL语句页面上的数据就变了”。更关键的是“MySQL成绩录入”这个功能点在框架里可能要写Model、Controller、View三层而在这里它浓缩成一个insert_mark.php文件前端用HTML表格批量输入学号、科目、分数后端用foreach($_POST[student_id] as $key $id)循环插入连预处理语句都用最直白的INSERT INTO scores (student_id, subject, score) VALUES ($id, $subject[$key], $score[$key])当然实际部署前我会教你怎么加mysqli_real_escape_string()防注入。这不是鼓励写不安全代码而是先建立“数据从键盘敲进去最终存进数据库”的完整心智模型——就像学骑车先不装辅助轮摔几次才记得重心在哪。这套系统真正解决的是“学习断层”问题。很多教程讲完echo Hello World就跳到Laravel中间缺了最关键的“如何把用户填的表单变成数据库里的一行记录”这一课。而这里的add_student_submit.php就是这堂课的教案它接收$_POST[name]、$_POST[class]拼接SQL执行mysqli_query()再用header(Location: management.php?msgsuccess)跳转并传参提示。20多个PHP文件每个都是一个独立的知识切片你可以单独打开modpwd.php研究密码修改逻辑不用先读懂整个框架的生命周期。提示别急着批评“没用预处理语句”。对新手而言先理解$sql UPDATE students SET password$new_pwd WHERE id$uid这行代码如何把变量塞进SQL比背诵PDO参数绑定语法重要十倍。等他亲手改出三次SQL语法错误自然会问“有没有更安全的方法”——那时你再教mysqli_prepare()他眼睛是亮的。2. 系统架构与角色权限设计两个入口一套底层逻辑很多人以为“学生查分”和“教师录分”是两套独立系统其实它们共享同一套数据库和核心逻辑区别仅在于会话校验规则和页面渲染分支。这种设计不是偷懒而是刻意展示Web权限控制的本质不是靠框架的auth装饰器而是靠$_SESSION[role]这个变量在每页开头做判断。2.1 双入口的底层真相系统有两个首页入口index.html学生登录页和teacher.php教师登录页但它们最终都指向同一个认证脚本check_session_login.php。这个文件干了三件事1. 连接MySQL数据库$conn mysqli_connect($host, $user, $pwd, $db)2. 根据登录页传来的$_POST[role]参数决定查哪张表if($_POST[role]student) $tablestudents; else $tableteachers;3. 执行查询后用$_SESSION[role] $_POST[role]; $_SESSION[id] $row[id];存储身份信息这意味着你完全可以在index.html里把input typehidden namerole valueteacher然后用学生账号密码登录教师后台——当然系统后续会在management.php里用if($_SESSION[role]!teacher) die(无权访问);拦住。这种“明面上分离底层统一”的设计让新手一眼看懂权限控制的物理实现它就是几个if判断和$_SESSION变量的组合。2.2 数据库设计一张表解决所有关系整个系统只用4张表却覆盖了学生档案、成绩、教师、密码重置需求-students表id(主键),name,class,phone,password,created_at-scores表id,student_id(外键),subject,score,updated_at-teachers表id,username,password,real_name,created_at-pwd_reset_tokens表id,user_id,token,expires_at重点说说scores表的设计巧思。它没有为每科设单独字段如math_score,english_score而是用“行”来存储科目。这样做的好处是新增科目比如加一门“人工智能导论”无需ALTER TABLE只要往scores表插新记录就行。学生查分时stuinfo.php执行SELECT subject, score FROM scores WHERE student_id ?结果直接循环输出教师录分时insert_mark.php接收$_POST[subject]数组循环插入多行。这种设计让新手第一次理解“范式化”的实际价值——不是为了考试而是为了未来少改几行代码。2.3 文件职责划分每个PHP文件只做一件事压缩包里20多个PHP文件命名规则全是动词名词add_student_submit.php、update_mark_submit.php这是刻意为之的“单一职责”训练。以update_mark.php为例它只做一件事根据URL参数?id5查出ID为5的成绩记录渲染一个带预填充值的HTML表单而真正的更新操作由update_mark_submit.php完成——它接收表单POST执行UPDATE SQL然后跳转回management.php。这种拆分强迫新手思考“显示页面”和“处理数据”必须分离否则容易写出把HTML和SQL混在一起的“意大利面代码”。注意check_session_login.php是唯一被多个入口调用的“公共函数”但它不渲染任何HTML只负责认证和跳转。这种复用方式比教新手写include config.php更直观——你看得见它被谁调用、返回什么结果。3. 核心功能实操详解从建库到批量录分的完整链路现在我们动手跑通整个流程。假设你有一台装了XAMPP的Windows电脑Mac用户用MAMPLinux用户用LAMP以下是真实操作步骤不是理论描述。3.1 数据库一键导入三分钟建好所有表打开phpMyAdmin通常是http://localhost/phpmyadmin点击左上角“新建”输入数据库名student_system排序规则选utf8mb4_general_ci支持中文和emoji。接着点击“导入”选择压缩包里的student_system.sql文件。这个SQL脚本包含三部分-- 1. 创建students表 CREATE TABLE students ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL, class varchar(20) NOT NULL, phone varchar(15) DEFAULT NULL, password varchar(255) NOT NULL, created_at timestamp DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 2. 插入测试数据教师账号 INSERT INTO teachers (username, password, real_name) VALUES (admin, $2y$10$9Xz...hash..., 张老师); -- 3. 添加外键约束确保成绩表student_id存在 ALTER TABLE scores ADD CONSTRAINT fk_student_id FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE CASCADE;执行后你会看到4张表出现在左侧列表。特别注意teachers表里的密码是bcrypt加密的$2y$10$...开头这是teachermodpwd.php里用password_hash()生成的。如果你忘了初始密码可以直接执行UPDATE teachers SET passwordpassword_hash(123456, PASSWORD_DEFAULT) WHERE usernameadmin;重置。3.2 学生查分全流程从登录到看到自己的数学92分浏览器打开http://localhost/student_system/index.html注意不是PHP文件是纯静态HTML输入学生账号stu001密码123456点击登录 → 跳转到check_session_login.php该脚本验证通过后执行header(Location: stuinfo.php);此时浏览器地址栏变成http://localhost/student_system/stuinfo.phpstuinfo.php开始执行先检查if(!isset($_SESSION[id]) || $_SESSION[role]!student) die(请先登录);再连接数据库执行php $sql SELECT s.name, s.class, sc.subject, sc.score FROM students s JOIN scores sc ON s.id sc.student_id WHERE s.id .$_SESSION[id]; $result mysqli_query($conn, $sql);循环$result用trtd?php echo $row[subject]; ?/tdtd?php echo $row[score]; ?/td/tr输出表格你会发现stuinfo.php里没有任何JavaScript所有交互靠PHP完成。如果学生想改密码点击页面上的“修改密码”链接跳转到stu_update_info.php这个页面会显示一个表单提交后由stu_update_info_submit.php处理——整个过程像流水线每个环节都清晰可见。3.3 教师批量录分三步搞定50个学生的期中成绩这才是体现系统实用性的核心场景。传统做法是一个个点开学生编辑页手动输分数而这里用HTML表格实现批量操作教师登录后进入management.php点击“批量录分”按钮跳转到insert_mark.phpinsert_mark.php生成一个动态表格html学号姓名数学英语物理提交成绩3. insert_mark_submit.php接收数据循环插入phpfor($i0; $icount($_POST[‘student_id’]); $i) {$sid $_POST[‘student_id’][$i];// 分别插入三科成绩mysqli_query($conn, “INSERT INTO scores (student_id, subject, score) VALUES ($sid, ‘数学’, {$_POST[‘math_score’][$i]})”);mysqli_query($conn, “INSERT INTO scores (student_id, subject, score) VALUES ($sid, ‘英语’, {$_POST[‘english_score’][$i]})”);mysqli_query($conn, “INSERT INTO scores (student_id, subject, score) VALUES ($sid, ‘物理’, {$_POST[‘physics_score’][$i]})”);}实测下来录50个学生3科成绩填表提交不到2分钟。这个功能的价值在于它用最基础的HTML表单和PHP循环解决了教育场景中最频繁的操作痛点而且代码一目了然——新手能立刻模仿着改成“语文、化学、生物”四科。4. 安全加固与生产部署从实验室到真实环境的必经之路这套系统在教学环境中运行完美但若要放到学校内网甚至公网必须补上几块“安全垫”。这不是可选项而是每个PHP开发者的职业本能。4.1 密码存储从明文到bcrypt的升级路径原始代码里add_student_submit.php用md5($_POST[password])存密码这在2024年是严重安全隐患。正确做法是替换为password_hash()// 替换前危险 $password_hash md5($_POST[password]); // 替换后推荐 $password_hash password_hash($_POST[password], PASSWORD_DEFAULT);同时登录验证也要改// 替换前 if($row[password] md5($_POST[pwd])) { /* 登录成功 */ } // 替换后 if(password_verify($_POST[pwd], $row[password])) { /* 登录成功 */ }PASSWORD_DEFAULT目前是bcrypt未来PHP升级会自动切换到更强算法无需改代码。这个改动只需5分钟却能让系统抵御彩虹表攻击。4.2 SQL注入防护三招构建防火墙原始代码大量使用字符串拼接SQL如SELECT * FROM students WHERE id .$_GET[id]。修复方案分三级-初级立即生效用mysqli_real_escape_string()过滤所有用户输入php $safe_id mysqli_real_escape_string($conn, $_GET[id]); $sql SELECT * FROM students WHERE id $safe_id;-中级推荐改用预处理语句Prepared Statementsphp $stmt mysqli_prepare($conn, SELECT * FROM students WHERE id ?); mysqli_stmt_bind_param($stmt, i, $_GET[id]); // i表示整数 mysqli_stmt_execute($stmt);-高级长期主义在check_session_login.php开头添加全局过滤php function sanitize_input($data) { $data trim($data); $data stripslashes($data); $data htmlspecialchars($data); return $data; } $_POST array_map(sanitize_input, $_POST); $_GET array_map(sanitize_input, $_GET);4.3 会话安全防止Session Fixation和劫持原始代码的session_start()没有配置安全参数。生产环境必须加上// 在所有PHP文件最开头比session_start()还早 ini_set(session.cookie_httponly, 1); // 防止JS读取cookie ini_set(session.cookie_secure, 1); // 仅HTTPS传输部署到https时启用 ini_set(session.use_strict_mode, 1); // 防止Session Fixation session_start(); // 登录成功后立即regenerate ID if($login_success) { session_regenerate_id(true); // 销毁旧session }4.4 部署 checklist上线前必须核对的7件事检查项操作方法为什么重要1. 关闭错误报告在php.ini中设display_errors Off或在PHP文件开头加error_reporting(0);防止数据库密码等敏感信息暴露在错误页面上2. 限制目录浏览在项目根目录放.htaccess文件内容Options -Indexes避免黑客直接看到/uploads/目录下的文件列表3. 移除调试文件删除压缩包里的.~介绍文档.docx、.gitignore、.inscode等临时文件减少攻击面避免泄露编辑器配置信息4. 修改默认账号执行SQLUPDATE teachers SET usernameyour_admin, passwordpassword_hash(your_strong_pwd, PASSWORD_DEFAULT) WHERE id1;防止使用默认admin/123456被暴力破解5. 设置文件权限Linux下执行chmod 644 *.php *.html *.css和chmod 755 uploads/防止PHP文件被意外写入恶意代码6. 数据库连接隔离将$host,$user,$pwd等信息移到config.php并设chmod 600 config.php避免数据库凭据硬编码在每个PHP文件里7. 启用HTTPS重定向.htaccess中添加RewriteEngine OnRewriteCond %{HTTPS} offRewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R301]强制加密传输防止登录凭证被嗅探实操心得我在某中学部署时曾因忘记第1项导致mysqli_connect()失败时直接打印出mysql_user:root, mysql_pwd:123456在页面上。后来每次上线前都用这段代码快速检测php ?php if(ini_get(display_errors)) { die(警告display_errors未关闭请修改php.ini); } echo 安全检查通过; ?5. 常见问题排查与二次开发指南那些文档里不会写的坑即使按文档一步步操作新手仍会遇到一些“意料之外”的问题。这些不是Bug而是PHP运行环境的特性。我把三年来收集的高频问题整理成速查表并附上独家解决方案。5.1 典型问题速查表问题现象可能原因解决方案经验备注登录后空白页URL停留在check_session_login.phpsession_start()前有空格或BOM头用Notepad打开所有PHP文件 → 编码 → 转为UTF-8无BOM格式Windows记事本保存的PHP文件自带BOM会导致headers already sent错误stuinfo.php显示“未登录”但明明刚输过账号密码session_start()未在每个PHP文件开头调用检查stuinfo.php第一行是否为?php session_start();确认没有空行或空格PHP的session机制要求每个使用$_SESSION的文件都必须先session_start()批量录分时只插入了第一个学生的成绩for循环中SQL语句缺少分号或引号不匹配在insert_mark_submit.php中临时加echo $sql; die();查看生成的SQL语句新手常犯错误VALUES ($sid, 数学, $_POST[math_score][$i])漏了$符号修改学生资料后页面跳转到management.php?msgsuccess但没显示提示management.php里没有处理$_GET[msg]的代码在management.php的HTML顶部添加?php if(isset($_GET[msg]) $_GET[msg]success): ?div classalert操作成功/div?php endif; ?原始代码的提示逻辑分散在各处建议统一用CSS类.alert控制样式phpMyAdmin导入SQL时报错“#1046 - No database selected”没有先创建数据库或SQL文件里缺少USE student_system;在SQL文件最开头添加CREATE DATABASE IF NOT EXISTS student_system CHARACTER SET utf8mb4; USE student_system;大多数新手以为导入SQL会自动建库其实需要手动创建或SQL里声明5.2 二次开发实战给系统加一个“成绩统计”功能很多老师需要知道班级平均分、最高分。原始系统没这个功能但扩展起来只要3个文件statistics.php前端页面在management.php里加个链接a hrefstatistics.php成绩统计/a然后创建statistics.phpphp成绩统计各科成绩统计科目平均分最高分最低分及格率60 THEN 1 ELSE 0 END) pass FROM scores WHERE subject$sub; $res mysqli_query($conn, $sql); $row mysqli_fetch_assoc($res); $pass_rate $row[total] ? round($row[pass]/$row[total]*100,1) : 0; echo $sub.round($row[avg],2).{$row[max]}{$row[min]}{$pass_rate}%; } ?export_csv.php导出Excel在statistics.php里加个按钮点击后执行phpconfig.php统一配置创建config.php把数据库连接信息集中管理php 然后在所有PHP文件开头改为require_once ‘config.php’;这个扩展案例的价值在于它展示了如何在不破坏原有结构的前提下用最小成本增加新功能。所有新增代码都遵循原始系统的风格——没有框架、没有复杂依赖就是纯粹的PHPMySQL。6. 教学价值再挖掘如何用这套系统讲透PHP核心概念作为一线讲师我发现这套系统是绝佳的“概念锚点”。当学生抽象地学“面向对象”时你让他看management.php里重复出现的mysqli_connect()他立刻明白“为什么要封装成函数”当他困惑“什么是MVC”时你指着update_mark.phpView、update_mark_submit.phpController、scores表Model他豁然开朗。6.1 用真实代码讲解PHP核心机制超全局变量让学生在check_session_login.php里打断点观察$_POST如何接收表单数据$_SESSION如何跨页面传递用户ID文件包含把mysqli_connect()提取到db_connect.php演示require_once如何避免重复连接表单处理对比stu_update_info.php显示表单和stu_update_info_submit.php处理提交讲解HTTP GET/POST区别错误处理故意把mysqli_query()的SQL写错在add_student_submit.php里加or die(mysqli_error($conn))让学生亲眼看到错误信息。6.2 课程设计进阶任务清单给学生布置渐进式任务从模仿到创新1.基础任务修改style.css把蓝色主题改成绿色考察HTML/CSS基础2.逻辑任务在scores表里加semester字段如“2024春”修改所有成绩相关PHP文件支持按学期筛选考察SQL和PHP逻辑3.安全任务将所有md5()替换为password_hash()并修改登录验证逻辑考察安全意识4.扩展任务增加“家长查看”角色要求家长只能看自己孩子的成绩且不能修改考察权限控制深度5.综合任务用原生JavaScript重写stuinfo.php的成绩排序功能点击表头按分数升序/降序不刷新页面考察前后端协作最后分享一个小技巧我在课堂上会让学生用手机扫描php学生管理系统.mov视频里的二维码直接跳转到GitHub仓库已脱敏处理。仓库里不仅有源码还有每个版本的commit记录——比如feat: add statistics page、fix: prevent sql injection in update_mark_submit.php。学生能看到真实的开发迭代过程理解“写代码”不是一蹴而就而是不断修复、优化、重构的旅程。这套系统真正的价值不在于它多完美而在于它足够真实真实到能让新手第一次触摸到软件开发的温度。本文还有配套的精品资源点击获取简介纯原生PHP写的学生成绩管理程序不依赖Laravel、ThinkPHP等任何框架也不用Composer、路由或模板引擎只靠基础PHPMySQLHTMLCSSJS就能跑起来。系统分学生和教师两个入口学生登录后能看自己各科成绩、改密码和基本信息教师登录后可以增删改查学生档案、批量录成绩、单条修改分数、重置学生密码。所有PHP文件都是手写逻辑比如add_student_submit.php处理新增学生update_mark_submit.php更新分数check_session_login.php做登录校验代码带中文注释结构一目了然。压缩包里有全部前端页面index.html、style.css、swiper.min.css等、后端PHP脚本共20多个核心文件、建库建表的SQL文件直接phpMyAdmin导入就行、Word版图文说明文档、项目结构图还有一个实操演示视频php学生管理系统.mov从环境部署到功能操作全涵盖。适合PHP初学者练手、课程设计参考或快速搭建轻量教学管理后台。本文还有配套的精品资源点击获取