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

汽车租赁系统开发问题:如何筛选指定日期可用车辆

汽车租赁系统:日期查询与可用车辆筛选解决方案

原代码核心问题

  • 日期处理遗漏年份:仅保留m-d格式,会导致跨年预订的判断错误(如12-30至01-02的预订,与次年12-30的查询会误判无冲突)。
  • 表关联逻辑混乱:嵌套循环遍历所有预订和车辆,且stmt2遍历一次后无法重复获取数据,导致后续循环失效。
  • 冲突判断逻辑不全:现有条件无法覆盖所有时间段重叠场景,无法准确识别占用车辆。
  • 效率低下:全量查询后在PHP中筛选,数据量大时性能极差。
  • 缺乏安全防护:未使用参数化查询,存在SQL注入风险。

一、正确的日期冲突判断逻辑

用户选择的时间段(pickupDate-returnDate)与已有预订(start_date-end_date)存在冲突的判定规则:

用户取车日期 ≤ 预订结束日期 且 用户还车日期 ≥ 预订开始日期

反过来,可用车辆即为:没有任何预订满足上述冲突条件的车辆,或从未被预订过的车辆。


二、修正后的完整代码

<!--Car Cover-->
<?php 
if(isset($_POST['submit'])) {
    // 获取用户输入
    $pickupDate = $_POST['pickupDate'];
    $returnDate = $_POST['returnDate'];

    // 非空验证
    if(empty($pickupDate)) {
        $_SESSION['ErrorMessage'] = "取车日期不能为空";
        TakeTo("index");
    } elseif(empty($returnDate)) {
        $_SESSION['ErrorMessage'] = "还车日期不能为空";
        TakeTo("index");
    }

    // 转换为DateTime对象,保留完整日期(含年份)
    $startDt = new DateTime($pickupDate);
    $endDt = new DateTime($returnDate);

    // 日期逻辑验证
    if($startDt->format('Y-m-d') === $endDt->format('Y-m-d')) {
        $_SESSION['ErrorMessage'] = "租车时长至少1天";
        TakeTo("index");
    } elseif($endDt < $startDt) {
        $_SESSION['ErrorMessage'] = "还车日期不能早于取车日期";
        TakeTo("index");
    }

    // 参数化SQL:直接从数据库筛选可用车辆
    $sql = "
        SELECT c.* 
        FROM cars c
        LEFT JOIN reservations r ON c.id = r.selected_car
        WHERE r.selected_car IS NULL 
        OR NOT (
            :pickup_date <= r.end_date 
            AND :return_date >= r.start_date
        )
        GROUP BY c.id
    ";

    // 执行参数化查询,防止SQL注入
    $stmt = $con->prepare($sql);
    $stmt->bindParam(':pickup_date', $pickupDate);
    $stmt->bindParam(':return_date', $returnDate);
    $stmt->execute();

    // 输出结果
    echo "搜索日期:{$pickupDate} 至 {$returnDate}<br>";
    if($stmt->rowCount() > 0) {
        while($car = $stmt->fetch()) {
            echo "车辆名称:{$car['car_name']} - 生产年份:{$car['production_year']} - 发动机:{$car['engine']} - 车辆ID:{$car['id']}<br>";
        }
    } else {
        echo "该时间段内没有可用车辆";
    }
}
?>

代码关键说明

  1. 日期处理优化:保留Y-m-d完整日期格式,用DateTime对象直接比较,避免跨年判断错误。
  2. 参数化查询:通过prepare和bindParam绑定用户输入,彻底规避SQL注入风险。
  3. SQL关联筛选:
    • 左连接cars与reservations表,通过车辆ID关联数据;
    • r.selected_car IS NULL筛选从未被预订的车辆;
    • NOT (...)排除存在冲突预订的车辆;
    • GROUP BY c.id确保同一车辆仅返回一次。
  4. 逻辑简化:直接从数据库获取结果,无需在PHP中遍历全量数据,代码更简洁高效。

额外优化建议

  • 数据库中reservations表的start_date、end_date设置为DATE类型,保证日期存储规范;
  • 给reservations.selected_car与cars.id建立外键约束,维护数据一致性;
  • 增加日期格式验证(如用DateTime::createFromFormat),确保用户输入合法日期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:10:40