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

PHP实现租车时间段冲突校验及同车型多车辆可用性查询方案咨询

车辆时段可用性校验PHP实现思路

一、核心逻辑前置约定

  • 所有日期统一转换为DateTime对象或者Unix时间戳计算,避免字符串格式不一致导致的判断错误
  • 时段冲突判定规则:两个时间段 [A开始, A结束]、[B开始, B结束] 存在冲突的条件为 A开始 < B结束 且 A结束 > B开始,该规则覆盖所有重叠、包含、首尾部分重叠的场景;如果业务允许还车当日可直接再次出租,可把大于/小于调整为大于等于/小于等于适配规则
  • 示例中用户请求时段27-11-2021至29-11-2021,与已租时段27-11-2021至28-11-2021符合冲突判定条件

二、单车辆可用性校验实现

封装独立判断函数,可复用在各类校验场景:

/**
 * 校验单车辆在指定时段是否可租
 * @param string $reqStart  用户请求的租用开始日期 格式d-m-Y
 * @param string $reqEnd    用户请求的租用结束日期 格式d-m-Y
 * @param array $rentedPeriods 车辆已生效预订时段数组 每个元素结构为['start' => 'd-m-Y日期', 'end' => 'd-m-Y日期']
 * @return bool 可租返回true 不可租返回false
 */
function isVehicleAvailable(string $reqStart, string $reqEnd, array $rentedPeriods): bool
{
    // 固定格式转换用户请求日期为时间戳,避免日期格式识别错误
    $reqStartTime = DateTime::createFromFormat('d-m-Y', $reqStart)->getTimestamp();
    $reqEndTime = DateTime::createFromFormat('d-m-Y', $reqEnd)->getTimestamp();
    
    foreach ($rentedPeriods as $period) {
        $rentedStart = DateTime::createFromFormat('d-m-Y', $period['start'])->getTimestamp();
        $rentedEnd = DateTime::createFromFormat('d-m-Y', $period['end'])->getTimestamp();
        // 命中冲突规则直接返回不可用
        if ($reqStartTime < $rentedEnd && $reqEndTime > $rentedStart) {
            return false;
        }
    }
    return true;
}

三、同车型多车辆批量校验实现

先拉取对应车型下全部车辆,逐个校验可用性后返回可用车辆列表:

/**
 * 查询指定车型下所有符合时段要求的可用车辆
 * @param string $modelId 目标车型ID
 * @param string $reqStart 租用开始日期
 * @param string $reqEnd 租用结束日期
 * @param PDO $pdo 数据库连接实例
 * @return array 可用车辆ID列表,无可用车辆返回空数组
 */
function getAvailableVehiclesByModel(string $modelId, string $reqStart, string $reqEnd, PDO $pdo): array
{
    $availableVehicles = [];
    // 第一步:拉取该车型下所有上线车辆
    $stmt = $pdo->prepare("SELECT id FROM vehicles WHERE model_id = ? AND status = 1");
    $stmt->execute([$modelId]);
    $vehicleIds = $stmt->fetchAll(PDO::FETCH_COLUMN);
    
    foreach ($vehicleIds as $vid) {
        // 拉取该车辆所有已生效、未取消的预订时段
        $stmt = $pdo->prepare("SELECT start_date, end_date FROM bookings WHERE vehicle_id = ? AND status = 1 AND end_date >= ?");
        $stmt->execute([$vid, $reqStart]);
        $rentedPeriods = $stmt->fetchAll(PDO::FETCH_ASSOC);
        // 校验通过则加入可用列表
        if (isVehicleAvailable($reqStart, $reqEnd, $rentedPeriods)) {
            $availableVehicles[] = $vid;
        }
    }
    return $availableVehicles;
}

四、性能优化建议

  • 数据量较大时可将冲突判断逻辑下沉到SQL层,直接通过数据库查询过滤可用车辆,减少PHP与数据库的IO交互次数
  • 给bookings表添加vehicle_id、start_date、end_date联合索引,大幅提升时段查询效率
  • 查询已租时段时提前过滤已过期的历史订单,减少参与冲突判断的数据量

内容的提问来源于stack exchange,提问作者shams

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:06:02