PHP+MySQL酒店预订系统多预订场景房间可用性查询异常问题
问题定位
- 核心错误1:行级匹配逻辑缺陷
LEFT JOIN后每条已存在的预订对应一行结果,原WHERE条件仅判断单条预订是否和新预订无冲突,只要房间存在任意一条不冲突的预订(比如你案例里的预订2),就会判定房间可用,完全忽略同房间其他冲突的预订记录。 - 核心错误2:存在SQL注入风险+未过滤无效预订
原代码直接把房型参数$LeChoix拼接进SQL语句,存在注入风险;同时没有加预订有效状态的过滤条件,已取消、已完成的无效预订也会参与校验,容易引发额外误判。
正确实现方案
核心逻辑
先筛选出所有指定房型、目标时段存在有效冲突预订的房间ID,再取反排除这些房间,剩下的就是符合要求的可用房间。
两个预订时段冲突的判定公式:新预订开始时间 < 已有预订结束时间 AND 新预订结束时间 > 已有预订开始时间,该规则覆盖了完全重合、部分重叠、首尾相接等所有冲突场景。
修正后的代码
// 参数说明:$DateDebut为新预订开始日期,$DateFin为新预订结束日期,$LeChoix为目标房型 $stmt = $conn->prepare(" SELECT T_Chambres.NoChambre FROM T_Chambres WHERE T_Chambres.TypeChambre = ? AND T_Chambres.NoChambre NOT IN ( SELECT DISTINCT RefChambre FROM T_Reservation WHERE -- 仅校验有效状态的预订,可根据你的实际业务字段调整状态值,比如1代表有效预订 T_Reservation.Status = 1 AND DateDebutRes < ? AND DateFinRes > ? ) LIMIT 1 "); // 参数绑定顺序:房型、新预订结束时间、新预订开始时间 $stmt->bind_param("sss", $LeChoix, $DateFin, $DateDebut); $stmt->execute();
效果验证
你提到的多预订异常场景中,新预订2021-10-25至2021-10-27会和已存在的有效预订1匹配上冲突条件,对应房间号会被加入子查询的排除列表,外层查询不会返回该房间,符合预期判断逻辑。
内容的提问来源于stack exchange,提问作者Chawki
相关产品推荐
相关产品推荐

