mysql菜鸟教程

专栏导航

18.4 实战:开发简单的学生管理系统

18.4 实战:开发简单的学生管理系统

本节我们将从零开始,利用 PHP 和 MySQL 构建一个简单的学生管理系统。系统虽小,但覆盖了 Web 开发的核心环节:数据库设计、后端逻辑处理、前后端数据交互。完成本项目后,你将具备开发基础信息管理系统的能力。

一、功能需求

  • 展示所有学生列表

  • 添加新学生

  • 修改已有学生信息

  • 删除学生记录

  • 按姓名或学号搜索学生

二、环境准备

  • PHP 7.4+(推荐 8.0+)

  • MySQL 5.7+ 或 MariaDB

  • Web 服务器(Apache / Nginx),这里以 Apache 为例

  • 代码编辑器(VS Code 等)

将项目放在 Web 服务器的根目录下,例如 student_manage 文件夹。

三、数据库设计

创建一个名为 student_db 的数据库,并在其中建立 students 表:

CREATE DATABASE IF NOT EXISTS student_db 
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE student_db;
CREATE TABLE students (
    id INT AUTO_INCREMENT PRIMARY KEY,
    student_id VARCHAR(20NOT NULL UNIQUE COMMENT '学号',
    name VARCHAR(50NOT NULL COMMENT '姓名',
    gender ENUM('男','女'NOT NULL COMMENT '性别',
    age TINYINT UNSIGNED NOT NULL COMMENT '年龄',
    class VARCHAR(50) COMMENT '班级',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入几条测试数据方便调试:

INSERT INTO students (student_id, name, gender, age, class)  VALUES('2024001', '张三', '男', 20, '计算机科学1班'),  ('2024002', '李四', '女', 21, '计算机科学2班'),  ('2024003', '王五', '男', 19, '软件工程1班');

四、项目结构

student_manage/ ├── config.php          # 数据库配置与连接 ├── index.php           # 学生列表与搜索(主页面) ├── add.php             # 添加学生页面(表单+处理) ├── edit.php            # 编辑学生页面 ├── delete.php          # 删除学生逻辑 └── style.css           # 简单样式

第一步:数据库连接配置文件

config.php 负责连接 MySQL,并提供获取连接的函数。使用 mysqli 扩展(面向过程风格,易于理解)。

<?php
// config.php
define('DB_HOST''localhost');
define('DB_USER''root');
define('DB_PASS''');          // 根据实际环境填写密码
define('DB_NAME''student_db');
// 创建连接
$conn mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
// 检查连接
if (!$conn) {
    die("数据库连接失败: " . mysqli_connect_error());
}
// 设置字符集
mysqli_set_charset($conn"utf8mb4");

其他页面只需 require_once 'config.php'; 即可使用 $conn

第二步:学生列表与搜索(index.php)

主页面展示所有学生,提供搜索框、添加按钮,每条记录有编辑和删除操作。支持按学号或姓名模糊查询。

<?php
require_once 'config.php';
// 处理搜索
$search $_GET['search'] ?? '';
$where '';
if (!empty($search)) {
    // 转义防注入
    $search_esc mysqli_real_escape_string($conn$search);
    $where "WHERE student_id LIKE '%{$search_esc}%' "
    +"OR name LIKE '%{$search_esc}%'";
}
$sql "SELECT * FROM students {$where} ORDER BY id DESC";
$result mysqli_query($conn$sql);
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>学生管理系统</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<div>
    <h1>学生管理系统</h1>
    <div>
        <form action="index.php" method="get">
            <input type="text" name="search" placeholder="输入学号或姓名搜索"
             value="<?php echo htmlspecialchars($search); ?>">
            <button type="submit">搜索</button>
            <a href="index.php">显示全部</a>
        </form>
        <a href="add.php">添加新学生</a>
    </div>
    <table border="1" cellpadding="8" cellspacing="0">
        <thead>
            <tr>
                <th>ID</th>
                <th>学号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>班级</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
        <?php if (mysqli_num_rows($result) > 0): ?>
            <?php while ($row mysqli_fetch_assoc($result)): ?>
            <tr>
                <td><?php echo $row['id']; ?></td>
                <td><?php echo htmlspecialchars($row['student_id']); ?></td>
                <td><?php echo htmlspecialchars($row['name']); ?></td>
                <td><?php echo $row['gender']; ?></td>
                <td><?php echo $row['age']; ?></td>
                <td><?php echo htmlspecialchars($row['class']); ?></td>
                <td>
                    <a href="edit.php?id=<?php echo $row['id']; ?>">编辑</a>
                    <a href="delete.php?id=<?php echo $row['id']; ?>" 
                    onclick="return confirm('确认删除该学生吗?');">删除</a>
                </td>
            </tr>
            <?php endwhile?>
        <?php else?>
            <tr><td colspan="7">暂无学生数据</td></tr>
        <?php endif?>
        </tbody>
    </table>
</div>
</body>
</html>

要点:

  • 使用 mysqli_real_escape_string 防止 SQL 注入。

  • 输出时用 htmlspecialchars 避免 XSS 攻击。

  • 删除前用 JavaScript 确认,防止误操作。

第三步:添加学生(add.php)

添加页面同时展示表单和处理提交。使用 POST-Redirect-GET 模式避免重复提交,但简单系统直接在同文件判断即可。

<?php
require_once 'config.php';
$error '';
$success '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $student_id trim($_POST['student_id'] ?? '');
    $name       trim($_POST['name'] ?? '');
    $gender     $_POST['gender'] ?? '';
    $age        intval($_POST['age'] ?? 0);
    $class      trim($_POST['class'] ?? '');
    // 简单验证
    if ($student_id === '' || $name === '' || $gender === '' || $age <= 0) {
        $error '请完整填写所有必填字段。';
    } else {
        // 检查学号唯一性
        $check_sql "SELECT id FROM students WHERE student_id = ?";
        $stmt mysqli_prepare($conn$check_sql);
        mysqli_stmt_bind_param($stmt"s"$student_id);
        mysqli_stmt_execute($stmt);
        mysqli_stmt_store_result($stmt);
        if (mysqli_stmt_num_rows($stmt) > 0) {
            $error '该学号已存在,请更换。';
        } else {
            // 插入数据
            $insert_sql "INSERT INTO students "+
            "(student_id, name, gender, age, class) VALUES (?, ?, ?, ?, ?)";
            $stmt_insert mysqli_prepare($conn$insert_sql);
            mysqli_stmt_bind_param($stmt_insert, 
            "sssis"$student_id$name$gender$age$class);
            if (mysqli_stmt_execute($stmt_insert)) {
                $success '学生添加成功!';
                // 可重定向到首页,这里直接显示成功消息
            } else {
                $error '添加失败: ' . mysqli_error($conn);
            }
        }
    }
}
?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>添加学生</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<div>
    <h1>添加新学生</h1>
    <?php if ($error): ?>
        <p><?php echo $error?></p>
    <?php endif?>
    <?php if ($success): ?>
        <p><?php echo $success?> <a href="index.php">返回列表</a></p>
    <?php else?>
    <form method="post" action="add.php">
        <label>学号:<input type="text" name="student_id" required></label><br>
        <label>姓名:<input type="text" name="name" required></label><br>
        <label>性别:
            <select name="gender" required>
                <option value="">请选择</option>
                <option value="男">男</option>
                <option value="女">女</option>
            </select>
        </label><br>
        <label>年龄:<input type="number" name="age" min="1" max="150" required>
        </label><br>
        <label>班级:<input type="text" name="class"></label><br>
        <button type="submit">添加</button>
        <a href="index.php">取消</a>
    </form>
    <?php endif?>
</div>
</body>
</html>

此处使用预处理语句彻底杜绝 SQL 注入。

第四步:编辑学生(edit.php)

编辑功能先根据 ID 获取原有数据填充表单,提交时执行 UPDATE。

<?php require_once 'config.php'; $id = $_GET['id'] ?? 0; $id = intval($id); // 获取原有数据 $sql = "SELECT * FROM students WHERE id = ?"; $stmt = mysqli_prepare($conn, $sql); mysqli_stmt_bind_param($stmt, "i", $id); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $student = mysqli_fetch_assoc($result); if (!$student) {     die("学生不存在"); } $error = ''; $success = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') {     $student_id = trim($_POST['student_id'] ?? '');     $name       = trim($_POST['name'] ?? '');     $gender     = $_POST['gender'] ?? '';     $age        = intval($_POST['age'] ?? 0);     $class      = trim($_POST['class'] ?? '');

if ($student_id === '' || $name === '' || $gender === '' || $age <= 0) {         $error = '请完整填写所有必填字段。';     } else {         // 检查学号是否与其他记录冲突         $check_sql = "SELECT id FROM students WHERE student_id = ? AND id != ?";         $stmt_check = mysqli_prepare($conn, $check_sql);         mysqli_stmt_bind_param($stmt_check, "si", $student_id, $id);         mysqli_stmt_execute($stmt_check);         mysqli_stmt_store_result($stmt_check);         if (mysqli_stmt_num_rows($stmt_check) > 0) {             $error = '该学号已被其他学生使用。';         } else {             $update_sql = "UPDATE students SET student_id=?, name=?, gender=?, "+             "age=?, class=? WHERE id=?";             $stmt_update = mysqli_prepare($conn, $update_sql);             mysqli_stmt_bind_param($stmt_update, "sssisi", $student_id, $name, $gender,              $age, $class, $id);             if (mysqli_stmt_execute($stmt_update)) {                 $success = '学生信息更新成功!';                 // 重新获取更新后的数据                 $student['student_id'] = $student_id;                 $student['name'] = $name;                 $student['gender'] = $gender;                 $student['age'] = $age;                 $student['class'] = $class;             } else {                 $error = '更新失败: ' . mysqli_error($conn);             }         }     }}?><!DOCTYPE html><html lang="zh-CN"><head>     <meta charset="UTF-8">     <title>编辑学生</title>     <link rel="stylesheet" href="style.css"></head><body><div class="container">     <h1>编辑学生信息</h1>     <?php if ($error): ?>         <p class="error"><?php echo $error; ?></p>     <?php endif; ?>     <?php if ($success): ?>         <p class="success"><?php echo $success; ?> <a href="index.php">返回列表</a></p>     <?php endif; ?>     <form method="post" action="edit.php?id=<?php echo $id; ?>">         <label>学号:<input type="text" name="student_id" value="<?php echo htmlspecialchars($student['student_id']); ?>" required></label><br>         <label>姓名:<input type="text" name="name" value="<?php echo htmlspecialchars($student['name']); ?>" required></label><br>         <label>性别:            <select name="gender" required>                 <option value="男" <?php if($student['gender']==='男') echo 'selected'; ?>>男</option>                 <option value="女" <?php if($student['gender']==='女') echo 'selected'; ?>>女</option>             </select>         </label><br>         <label>年龄:<input type="number" name="age" value="<?php echo $student['age']; ?>" min="1" max="150" required></label><br>         <label>班级:<input type="text" name="class" value="<?php echo htmlspecialchars($student['class']); ?>"></label><br>         <button type="submit">保存修改</button>         <a href="index.php">取消</a>     </form></div></body></html>

第五步:删除学生(delete.php)

删除操作无需界面,直接处理 GET 参数,执行 DELETE 后重定向。

<?php require_once 'config.php'; $id = $_GET['id'] ?? 0; $id = intval($id); if ($id > 0) {     $sql = "DELETE FROM students WHERE id = ?";     $stmt = mysqli_prepare($conn, $sql);     mysqli_stmt_bind_param($stmt, "i", $id);     mysqli_stmt_execute($stmt); } // 重定向回列表页 header("Location: index.php");exit;

简单样式(style.css)

使界面更清爽:

body {     font-family: "Microsoft YaHei", sans-serif;     background: #f5f7fa;     margin: 0;     padding: 20px; } .container {     width: 900px;     margin: 0 auto;     background: #fff;     padding: 20px 30px;     border-radius: 8px;     box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h1 {     text-align: center;     color: #333; } .toolbar {     display: flex;     justify-content: space-between;     margin-bottom: 15px;}.search-form input {     padding: 6px;     width: 240px;}table {     width: 100%;     border-collapse: collapse;}th {     background: #4a90e2;     color: white;}td, th {     text-align: center;}a {     text-decoration: none;     margin: 0 5px;}.btn-add, .btn-reset {     padding: 8px 15px;     background: #4a90e2;     color: #fff;     border-radius: 4px;}.error {     color: #d9534f;     background: #f2dede;     padding: 8px;     border-radius: 4px;}.success {     color: #3c763d;     background: #dff0d8;     padding: 8px;     border-radius: 4px;}form label {     display: block;     margin: 12px 0;}form input, form select {     padding: 6px;     width: 260px;     margin-left: 8px;}button {     padding: 8px 20px;     cursor: pointer;}

运行与测试

  1. 启动 MySQL 和 Apache,导入数据库结构。

  2. 修改 config.php 中的数据库连接信息。

  3. 浏览器访问 http://localhost/student_manage/index.php

  4. 尝试搜索、添加、编辑、删除,观察功能是否正常。

安全与优化建议

  • 密码保护:实际项目中不应将数据库密码直接写在配置文件中,可使用环境变量。

  • 输入验证:前后端双重验证,年龄确保正整数。

  • CSRF 防护:为表单添加 token 防止跨站请求伪造。

  • 分页:当数据量大时,应增加分页功能,避免一次性加载所有记录。

  • 面向对象与框架:本实例采用面向过程,便于理解基础原理。生产环境可考虑使用 PDO、MVC 框架(如 Laravel、ThinkPHP)以提高开发效率和安全性。

所有评论

关于我 备案号:蜀ICP备2023042032号-1