docker拉取nignx 实现前后端连接的学生管理系统

一、准备

docker desktop

wamp(数据库)

二、docker拉取nignx

两条命令

docker pull nginx
docker run --name my-nginx -v /path/to/your/student_management_system:/usr/share/nginx/html:ro -p 8080:80 -d nginx

注意把/path/to/your/student_management_system换成自己的路径

路径是.html文件所在路径

三、数据库

打开wamp

打开phpMyAdmin网页,输入用户名root  初始登陆没有密码 回车确认

   ·点击“新建” → 输入数据库名:student_db → 创建

   ·选择刚创建的数据库 → 点击“SQL”标签 → 执行以下 SQL:

CREATE TABLE students (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    student_id VARCHAR(50) NOT NULL UNIQUE
);

这样就创建好一个数据表

四、后端API连接(php)

文件路径:wamp64/www/student_backend/api/student.php

<?php
header("Content-Type: application/json");

$conn = new mysqli("localhost", "root", "", "student_db");

if ($conn->connect_error) {
    die(json_encode(["status" => "error", "message" => "连接失败: " . $conn->connect_error]));
}

$method = $_SERVER['REQUEST_METHOD'];

switch ($method) {
    case 'GET':
        $result = $conn->query("SELECT * FROM students");
        if (!$result) {
            echo json_encode(["status" => "error", "message" => "查询失败"]);
            exit;
        }
        $students = [];
        while ($row = $result->fetch_assoc()) {
            $students[] = $row;
        }
        echo json_encode($students);
        break;

    case 'POST':
        $data = json_decode(file_get_contents('php://input'), true);
        $name = $conn->real_escape_string($data['name']);
        $student_id = $conn->real_escape_string($data['student_id']);

        // 检查学号是否已存在
        $check = $conn->query("SELECT * FROM students WHERE student_id = '$student_id'");
        if ($check->num_rows > 0) {
            echo json_encode(["status" => "error", "message" => "学号已存在"]);
            exit;
        }

        $stmt = $conn->prepare("INSERT INTO students (name, student_id) VALUES (?, ?)");
        $stmt->bind_param("ss", $name, $student_id);

        if ($stmt->execute()) {
            echo json_encode(["status" => "success"]);
        } else {
            echo json_encode(["status" => "error", "message" => "添加失败"]);
        }
        break;

    case 'DELETE':
        $data = json_decode(file_get_contents('php://input'), true);
        $id = $conn->real_escape_string($data['id']);

        $stmt = $conn->prepare("DELETE FROM students WHERE id = ?");
        $stmt->bind_param("i", $id);

        if ($stmt->execute()) {
            echo json_encode(["status" => "success"]);
        } else {
            echo json_encode(["status" => "error", "message" => "删除失败"]);
        }
        break;

    case 'PUT':
        $data = json_decode(file_get_contents('php://input'), true);
        $id = $conn->real_escape_string($data['id']);
        $name = $conn->real_escape_string($data['name']);
        $student_id = $conn->real_escape_string($data['student_id']);

        // 检查学号是否已被占用(排除自己)
        $check = $conn->query("SELECT * FROM students WHERE student_id = '$student_id' AND id != $id");
        if ($check->num_rows > 0) {
            echo json_encode(["status" => "error", "message" => "学号已被使用"]);
            exit;
        }

        $stmt = $conn->prepare("UPDATE students SET name = ?, student_id = ? WHERE id = ?");
        $stmt->bind_param("ssi", $name, $student_id, $id);

        if ($stmt->execute()) {
            echo json_encode(["status" => "success"]);
        } else {
            echo json_encode(["status" => "error", "message" => "更新失败"]);
        }
        break;

    default:
        echo json_encode(["status" => "error", "message" => "无效请求方法"]);
}
?>

五、html页面(html+css+js)

文件路径:student_management_system/index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>学生管理系统</title>
    <style>
        body {
            font-family: 'Segoe UI', system-ui;
            margin: 2rem auto;
            max-width: 1200px;
            padding: 0 20px;
            background: linear-gradient(150deg, #e6f0ff 0%, #f0f7ff 100%);
        }

        #studentForm {
            background: rgba(255,255,255,0.95);
            padding: 2rem;
            border-radius: 12px;
            box-shadow: 0 2px 15px rgba(59,130,246,0.05);
            display: flex;
            gap: 1rem;
            flex-wrap: wrap;
            margin-bottom: 2rem;
        }

        label {
            flex: 1;
            min-width: 200px;
            display: flex;
            gap: 0.5rem;
            align-items: center;
        }

        input {
            padding: 0.8rem;
            border: 2px solid #e2e8f0;
            border-radius: 8px;
            flex: 1;
            transition: border-color 0.3s ease;
        }

        input:focus {
            outline: none;
            border-color: #3b82f6;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            background: rgba(255,255,255,0.98);
            border-radius: 12px;
            overflow: hidden;
            box-shadow: 0 2px 15px rgba(59,130,246,0.05);
        }

        th {
            background: #1e3a8a;
            color: white;
            padding: 1rem;
            font-weight: 600;
            text-align: center;
        }

        td {
            padding: 1rem;
            border-bottom: 1px solid #e2e8f0;
            transition: transform 0.2s ease;
            text-align: center;
        }

        td:nth-child(4) {
            display: flex;
            gap: 0.5rem;
            justify-content: center;
        }

        tr:nth-child(even) {
            background: #f8fafc;
        }

        tr:hover td {
            background: #eff6ff;
            transform: scale(1.02);
        }

        button {
            padding: 0.6rem 1.2rem;
            border: none;
            border-radius: 8px;
            background: #3b82f6;
            color: white;
            font-weight: 500;
            transition: all 0.3s ease;
            display: inline-flex;
            gap: 0.5rem;
            align-items: center;
        }

        button:hover {
            background: #2563eb;
            box-shadow: 0 4px 6px rgba(59,130,246,0.2);
            transform: translateY(-1px);
        }

       
        h1 {
            text-align: center;
            margin: 1rem 0 2rem;
        }

        /* 在body样式中添加主容器包裹 */
        /* 统一注释语法 */
        .main-container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 0 20px;
        }
        
        /* 合并后的媒体查询 */
        @media (max-width: 768px) {
            .main-container {
                padding: 0 10px;
            }
            body {
                margin: 1rem;
            }
            #studentForm {
                flex-direction: column;
                padding: 1rem;
                gap: 0.8rem;
            }
            th:nth-child(1),
            td:nth-child(1) {
                display: none;
            }
        }
    </style>
</head>
<body>
    <h1>学生管理系统</h1>

    <form id="studentForm">
        <label>姓名:<input type="text" id="name" name="name" autocomplete="name" required></label>
        <label>学号:<input type="text" id="studentId" name="studentId" autocomplete="off" required></label>
        <button type="submit">添加学生</button>
    </form>

    <table id="studentTable">
        <thead>
            <tr>
                <th>ID</th>
                <th>姓名</th>
                <th>学号</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>

    <script>
        document.addEventListener("DOMContentLoaded", () => {
            const form = document.getElementById("studentForm");
            const tableBody = document.querySelector("#studentTable tbody");

            function loadStudents() {
                fetch("http://localhost/student_backend/api/student.php")
                    .then(res => res.json())
                    .then(students => {
                        tableBody.innerHTML = "";
                        students.forEach(student => {
                            const row = document.createElement("tr");
                            row.innerHTML = `
                                <td>${student.id}</td>
                                <td>${student.name}</td>
                                <td>${student.student_id}</td>
                                <td>
                                    <button onclick="editStudent(${student.id}, '${student.name}', '${student.student_id}')">编辑</button>
                                    <button onclick="deleteStudent(${student.id})">删除</button>
                                </td>
                            `;
                            tableBody.appendChild(row);
                        });
                    })
                    .catch(err => console.error("加载失败:", err));
            }

            form.addEventListener("submit", e => {
                e.preventDefault();
                const name = document.getElementById("name").value.trim();
                const studentId = document.getElementById("studentId").value.trim();

                if (!name || !studentId) {
                    alert("请输入完整信息!");
                    return;
                }

                fetch("http://localhost/student_backend/api/student.php", {
                    method: "POST",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify({ name, student_id: studentId })
                })
                .then(res => res.json())
                .then(data => {
                    if (data.status === "success") {
                        form.reset();
                        loadStudents();
                    } else {
                        alert(data.message || "添加失败");
                    }
                })
                .catch(err => console.error("请求错误:", err));
            });

            window.deleteStudent = id => {
                if (!confirm("确认删除?")) return;
                fetch("http://localhost/student_backend/api/student.php", {
                    method: "DELETE",
                    headers: { "Content-Type": "application/json" },
                    body: JSON.stringify({ id })
                })
                .then(() => loadStudents());
            };

            window.editStudent = (id, name, studentId) => {
                const newName = prompt("请输入新名字", name);
                const newId = prompt("请输入新学号", studentId);
                if (newName && newId) {
                    fetch("http://localhost/student_backend/api/student.php", {
                        method: "PUT",
                        headers: { "Content-Type": "application/json" },
                        body: JSON.stringify({ id, name: newName, student_id: newId })
                    })
                    .then(() => loadStudents());
                }
            };

            loadStudents();
        });
    </script>
</body>
</html>

六、访问地址:http://localhost:8080

实现页面:

七、问题

本文重在提供docker拉取nignx连接前后端思路,没有解决bug,即id自增的问题,如果删除对应的表中一列数据,新增一列数据只会继续叠加,不会补齐所缺id。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值