PHP MySQL预约系统:提取已预约时段并展示可用时段
解决PHP+MySQL预约系统的可用时段计算问题
这个需求我之前做线下门店预约系统时刚好碰到过,核心就是从已预约的时段中反向推导空闲区间,下面给你一步步拆解实现方案:
核心思路
- 先获取并整理已预约数据:从MySQL中拉取指定日期
$date的所有已预约时段,必须按预约开始时间升序排序,这样才能依次比对相邻时段的间隙。 - 初始化空闲区间起点:从当日的开始时间
$FirstStartTime开始。 - 遍历已预约时段生成空闲区间:
- 每次拿当前空闲起点和预约的开始时间对比,如果空闲起点更早,就把这个间隙加入可用列表。
- 然后把空闲起点更新为当前预约的结束时间,继续下一个预约的比对。
- 处理最后一段空闲区间:遍历完所有预约后,把最后一个预约的结束时间到当日结束时间
$lastEndTime的间隙加入列表(如果有效)。
完整函数实现
function createForAvailableHrs($FirstStartTime, $lastEndTime, $date) { $connector = new DbConnector(); // 假设你的数据库连接类正常工作 $availableSlots = []; // 1. 从数据库获取指定日期的已预约时段,按开始时间升序排序 $query = "SELECT start_time, end_time FROM appointments WHERE appointment_date = ? ORDER BY start_time ASC"; $stmt = $connector->prepare($query); $stmt->bind_param("s", $date); $stmt->execute(); $result = $stmt->get_result(); $bookedSlots = $result->fetch_all(MYSQLI_ASSOC); $stmt->close(); // 2. 初始化当前空闲时段的起点 $currentStart = $FirstStartTime; // 3. 遍历每个已预约时段,计算间隙 foreach ($bookedSlots as $slot) { $bookedStart = $slot['start_time']; $bookedEnd = $slot['end_time']; // 如果当前空闲起点早于预约开始时间,说明有可用间隙 if (strtotime($currentStart) < strtotime($bookedStart)) { $availableSlots[] = [ 'start' => $currentStart, 'end' => $bookedStart ]; } // 更新当前空闲起点为预约结束时间(如果预约结束时间更晚的话,防止重叠预约覆盖) if (strtotime($bookedEnd) > strtotime($currentStart)) { $currentStart = $bookedEnd; } } // 4. 处理最后一段空闲区间:从最后一个预约结束到当日结束时间 if (strtotime($currentStart) < strtotime($lastEndTime)) { $availableSlots[] = [ 'start' => $currentStart, 'end' => $lastEndTime ]; } return $availableSlots; }
关键注意事项
- 处理重叠预约:如果数据库里存在重叠的预约(比如A预约09:15-09:45,B预约09:30-10:00),上面的代码会自动合并成一个连续的占用时段,因为每次都会把
currentStart更新为最晚的结束时间。 - 时间格式一致性:确保
$FirstStartTime、$lastEndTime和数据库里的start_time、end_time都是相同的时间格式(比如H:i:s),避免strtotime解析出错。 - 无预约场景:如果指定日期没有任何预约,函数会直接返回一个包含
$FirstStartTime到$lastEndTime的完整区间。 - 全时段被预约场景:如果所有时段都被预约满了,函数会返回空数组,你可以在调用时做相应提示。
内容的提问来源于stack exchange,提问作者Geraldo Isaaks
相关产品推荐
相关产品推荐

