You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP MySQL预约系统:提取已预约时段并展示可用时段

解决PHP+MySQL预约系统的可用时段计算问题

这个需求我之前做线下门店预约系统时刚好碰到过,核心就是从已预约的时段中反向推导空闲区间,下面给你一步步拆解实现方案:

核心思路

  1. 先获取并整理已预约数据:从MySQL中拉取指定日期$date的所有已预约时段,必须按预约开始时间升序排序,这样才能依次比对相邻时段的间隙。
  2. 初始化空闲区间起点:从当日的开始时间$FirstStartTime开始。
  3. 遍历已预约时段生成空闲区间:
    • 每次拿当前空闲起点和预约的开始时间对比,如果空闲起点更早,就把这个间隙加入可用列表。
    • 然后把空闲起点更新为当前预约的结束时间,继续下一个预约的比对。
  4. 处理最后一段空闲区间:遍历完所有预约后,把最后一个预约的结束时间到当日结束时间$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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:45:01