课程报名满20人时从日历自动移除的实现方案咨询
搞定课程满员自动隐藏的方案,一步步来
我来帮你拆解这个需求,核心其实是统计报名人数和在日历查询时过滤满员课程两个关键点,咱们一步步实现:
1. 先搞定数据结构:确保能统计报名人数
首先你得有个方式记录每个课程的报名人数,两种常用方案选一个就行:
- 方案A:直接在
events表加字段:新增enrollment_count(INT类型,默认0),每次有人报名就更新这个数字。 - 方案B:单独建报名记录表:比如
enrollments表,字段包括event_id(关联课程ID)、user_id(报名用户ID),通过统计该表的记录数来得到报名人数。
2. 核心修改:日历显示时过滤满员课程
你现在的插入代码没问题,但日历展示课程的查询逻辑才是关键——只拉取报名人数小于20的课程,这才是实现“满员自动移除”的核心:
如果你用方案A(events表有enrollment_count):
修改查询日历事件的SQL,加个过滤条件:
// 示例:查询所有可显示的课程 $query = "SELECT * FROM events WHERE enrollment_count < 20"; // 如果你的日历按时间范围加载,就把条件叠加: // $query = "SELECT * FROM events WHERE start_event >= ? AND end_event <= ? AND enrollment_count < 20"; $result = mysqli_query($conn, $query); // 之后循环结果渲染日历即可
如果你用方案B(关联enrollments表):
用关联查询统计人数,再过滤:
$query = " SELECT e.*, COUNT(en.id) AS enrollment_count FROM events e LEFT JOIN enrollments en ON e.id = en.event_id GROUP BY e.id HAVING enrollment_count < 20 "; $result = mysqli_query($conn, $query);
这样满20人的课程根本不会被查出来,自然不会出现在日历上。
3. 管理员添加课程的补充逻辑
管理员添加课程时,只需要初始化报名人数就行(因为新课程肯定没人报名),修改你现有的插入代码:
if(isset($_POST["title"])) { // 先转义字段避免SQL注入(一定要做!) $title = mysqli_real_escape_string($conn, $_POST["title"]); $start_event = mysqli_real_escape_string($conn, $_POST["start_event"]); // 其他字段同理处理... // 插入时给enrollment_count设为0 $query = "INSERT INTO events (title, start_event, enrollment_count, ...) VALUES ('$title', '$start_event', 0, ...)"; mysqli_query($conn, $query); }
这里要注意必须做SQL注入防护,上面的mysqli_real_escape_string就是干这个的,别省略。
4. 报名功能的联动:确保人数统计准确
用户报名时,要同步更新人数,还要提前检查是否满员:
方案A的报名逻辑:
$event_id = $_POST["event_id"]; // 从表单拿到课程ID // 原子更新+检查,避免并发报名超员(重要!) $update_query = "UPDATE events SET enrollment_count = enrollment_count + 1 WHERE id = $event_id AND enrollment_count < 20"; mysqli_query($conn, $update_query); // 检查是否更新成功:受影响行数为0说明已经满员 if(mysqli_affected_rows($conn) == 0) { echo "抱歉,该课程报名人数已达上限,无法报名!"; } else { echo "报名成功!"; }
用UPDATE ... WHERE的原子操作能避免多个用户同时报名导致超20的问题,比先查询再更新更安全。
方案B的报名逻辑:
$event_id = $_POST["event_id"]; $user_id = $_SESSION["user_id"]; // 假设用户已登录,从会话拿ID // 先检查当前报名人数 $check_query = "SELECT COUNT(*) AS count FROM enrollments WHERE event_id = $event_id"; $check_result = mysqli_query($conn, $check_query); $row = mysqli_fetch_assoc($check_result); if($row["count"] < 20) { // 插入报名记录 $insert_query = "INSERT INTO enrollments (event_id, user_id) VALUES ($event_id, $user_id)"; mysqli_query($conn, $insert_query); echo "报名成功!"; } else { echo "抱歉,该课程报名人数已达上限!"; }
额外提醒
如果你的网站访问量不小,一定要用预处理语句代替直接拼接SQL,比如:
// 示例预处理语句(方案A的插入) $stmt = $conn->prepare("INSERT INTO events (title, start_event, enrollment_count) VALUES (?, ?, 0)"); $stmt->bind_param("ss", $title, $start_event); $stmt->execute();
这样能彻底避免SQL注入,比mysqli_real_escape_string更可靠。
内容的提问来源于stack exchange,提问作者Jessica Byers
相关产品推荐
相关产品推荐

