在传统的Web开发认知中,C语言通常被视为系统级编程语言,很少被用于Web后端开发。然而,通过CGI(Common Gateway Interface,通用网关接口)技术,C语言完全可以胜任Web后端开发工作。本教程将带你探索一个独特的全栈开发方案:使用C语言编写Web后端,配合原生HTML/CSS/JS构建前端界面,使用MySQL存储数据,开发一个完整的学生管理系统。
这种技术组合虽然不常见,但有助于深入理解HTTP协议的本质、Web服务器的运作原理、CGI的工作机制,以及C语言在网络编程中的实际应用。本教程将带你一步步实现一个功能完善的学生管理系统。
系统功能概述:
学生信息的增删改查(增加、删除、修改、查询)
学生按班级/年级筛选
学生成绩管理
响应式Web界面
技术架构图:
┌─────────────────────────────────────────────────────────────────┐
│ 用户浏览器 │
│ (HTML/CSS/JS 渲染前端页面) │
└─────────────────────────┬───────────────────────────────────────┘
│ HTTP请求
▼
┌─────────────────────────────────────────────────────────────────┐
│ Nginx/Apache Web服务器 │
│ (配置CGI支持) │
└─────────────────────────┬───────────────────────────────────────┘
│ 转发CGI请求
▼
┌─────────────────────────────────────────────────────────────────┐
│ CGI程序 (C语言) │
│ 解析HTTP请求 → 业务逻辑处理 → 生成HTML响应 → 返回客户端 │
└─────────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ MySQL数据库 │
│ 学生表 | 班级表 | 成绩表 │
└─────────────────────────────────────────────────────────────────┘
第一部分:系统架构与数据库设计
1.1 CGI技术原理
CGI(Common Gateway Interface) 是Web服务器与外部程序之间的标准接口。当用户请求一个CGI程序时,Web服务器会启动该程序,将HTTP请求信息通过环境变量和标准输入传递给程序,程序处理后将结果(通常是HTML)通过标准输出返回给Web服务器,再转发给客户端。
CGI工作流程:
用户在浏览器中访问一个URL(如http://localhost/cgi-bin/student.cgi)
Web服务器接收到请求,识别出这是CGI程序
服务器设置环境变量(如REQUEST_METHOD、QUERY_STRING、CONTENT_LENGTH等)
服务器启动CGI程序(fork一个进程)
CGI程序读取环境变量获取请求信息,通过标准输入读取POST数据
CGI程序执行业务逻辑,可能查询数据库
CGI程序通过标准输出输出HTTP响应头(如Content-Type: text/html)和响应体
Web服务器将响应转发给客户端浏览器
1.2 API接口设计
1.3 数据库设计
1.3.1 创建数据库
-- 创建学生管理系统数据库
CREATE DATABASE IF NOT EXISTS student_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE student_db;
1.3.2 班级表(classes)
-- 班级表:存储班级信息
CREATE TABLE `classes` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '班级ID',
`name` VARCHAR(50) NOT NULL COMMENT '班级名称,如:高一(1)班',
`grade` VARCHAR(20) NOT NULL COMMENT '年级,如:高一',
`classroom` VARCHAR(50) COMMENT '教室位置',
`class_teacher` VARCHAR(50) COMMENT '班主任姓名',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='班级表';
1.3.3 学生表(students)
-- 学生表:存储学生基本信息
CREATE TABLE `students` (
`id` INT NOT NULL AUTO_INCREMENT COMMENT '学生ID',
`student_no` VARCHAR(20) NOT NULL COMMENT '学号,唯一',
`name` VARCHAR(50) NOT NULL COMMENT '姓名',
`gender` ENUM('男', '女') NOT NULL COMMENT '性别',
`birth_date` DATE COMMENT '出生日期',
`class_id` INT NOT NULL COMMENT '所属班级ID',
`phone` VARCHAR(20) COMMENT '家长电话',
`address` VARCHAR(200) COMMENT '家庭地址',
`status` TINYINT DEFAULT 1 COMMENT '状态:0休学 1在读 2毕业',
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_student_no` (`student_no`),
KEY `idx_class_id` (`class_id`),
KEY `idx_name` (`name`),
FOREIGN KEY (`class_id`) REFERENCES `classes`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生表';
1.3.4 成绩表(scores)
-- 成绩表:存储学生各科成绩
CREATE TABLE `scores` (
`id` INT NOT NULL AUTO_INCREMENT,
`student_id` INT NOT NULL COMMENT '学生ID',
`subject` VARCHAR(50) NOT NULL COMMENT '科目:语文、数学、英语等',
`score` DECIMAL(5,2) NOT NULL COMMENT '分数',
`exam_date` DATE NOT NULL COMMENT '考试日期',
`semester` VARCHAR(20) COMMENT '学期:第一学期/第二学期',
PRIMARY KEY (`id`),
KEY `idx_student_id` (`student_id`),
FOREIGN KEY (`student_id`) REFERENCES `students`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='成绩表';
1.3.5 插入测试数据
-- 插入班级数据
INSERT INTO `classes` (`name`, `grade`, `class_teacher`) VALUES
('高一(1)班', '高一', '张老师'),
('高一(2)班', '高一', '李老师'),
('高二(1)班', '高二', '王老师'),
('高二(2)班', '高二', '赵老师');
-- 插入学生数据
INSERT INTO `students` (`student_no`, `name`, `gender`, `birth_date`, `class_id`, `phone`) VALUES
('2023001', '张三', '男', '2008-03-15', 1, '13800138001'),
('2023002', '李四', '女', '2008-05-20', 1, '13800138002'),
('2023003', '王小明', '男', '2008-08-10', 2, '13800138003');
-- 插入成绩数据
INSERT INTO `scores` (`student_id`, `subject`, `score`, `exam_date`, `semester`) VALUES
(1, '语文', 85.5, '2024-01-15', '第一学期'),
(1, '数学', 92.0, '2024-01-15', '第一学期'),
(1, '英语', 78.5, '2024-01-15', '第一学期'),
(2, '语文', 76.0, '2024-01-15', '第一学期'),
(2, '数学', 88.5, '2024-01-15', '第一学期');