如何在select下拉菜单中隐藏已占座选项 解决仅隐藏一个占座的问题
故障根因
- 外层结果集变量覆盖:外层查询
ticket表的结果集存在$rslt变量中,内层执行查询后重新给$rslt赋值,导致外层循环仅执行1次就终止,只能处理第一个已占座位。 - 座位过滤逻辑错误:你在已占座位的遍历循环中每次仅排除当前单个座位就输出所有剩余座位,最终下拉框会出现重复选项,且无法同时过滤所有已占座位。
- 原有业务逻辑冗余:最外层查询全量
ticket表的逻辑完全没必要,你应该直接基于前端传入的巴士编号、发车日期、发车时间三个参数查询对应班次的已占座位即可。 - 存在SQL注入风险:直接拼接
$_GET参数到SQL语句中,可能被恶意注入攻击,建议使用预处理语句。
修复代码
// 先获取前端传入的三个必要参数,实际生产建议做更严格的参数校验 $busnum = mysqli_real_escape_string($conn, $_GET['busnum']); $sch_date = mysqli_real_escape_string($conn, $_GET['sch_date']); // 前端选中的发车日期 $sch_time = mysqli_real_escape_string($conn, $_GET['sch_time']); // 前端选中的发车时间 // 第一步:查询当前班次所有已支付的已占座位,存入数组 $occupied_seats = []; $sel_occupied = "SELECT Tk_Chsn_Seat FROM ticket WHERE Bus_Plate_Number='$busnum' AND Tk_Sch_Date='$sch_date' AND Tk_Sch_Time='$sch_time' AND Tk_Stat='PAID'"; $rslt_occupied = mysqli_query($conn, $sel_occupied); if ($rslt_occupied->num_rows > 0) { while ($data = $rslt_occupied->fetch_assoc()) { $occupied_seats[] = $data['Tk_Chsn_Seat']; } } // 第二步:查询所有座位,过滤掉已占座位后输出选项 $sel_all_seats = "SELECT Seat_Num FROM seat ORDER BY Seat_Num ASC"; $rslt_seats = mysqli_query($conn, $sel_all_seats); if ($rslt_seats->num_rows > 0) { while ($row = $rslt_seats->fetch_assoc()) { $seat_num = $row['Seat_Num']; // 仅输出未被占用的座位 if (!in_array($seat_num, $occupied_seats)) { ?> <option value="<?= $seat_num ?>"><?= $seat_num ?></option> <?php } } }
逻辑说明
- 一次性查出当前班次所有已占座位存到数组中,避免循环查询数据库,性能更优
- 遍历所有座位时直接判断是否在已占数组中,可一次性过滤全部已占座位
- 每个查询的结果集使用独立变量名,避免了变量覆盖的问题
- 增加了参数转义操作,降低SQL注入风险
内容的提问来源于stack exchange,提问作者gellooo
相关产品推荐
相关产品推荐

