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

PHP与MySQL航班座位分配逻辑异常:跨日期分配错误求助

修复航空公司座位分配逻辑错误

嘿,我帮你找出了座位分配代码里的两个核心问题,马上就能修复好,赶你的校园项目时间完全没问题!

你的问题是跨日期预订4人时无法分配同一排的连续座位,根源在于SQL查询逻辑错误和全局变量导致的状态残留,具体分析和修复方案如下:

问题1:SQL查询的逻辑优先级错误

你的WHERE子句里,座位检查的OR条件没有正确和前面的航班/日期条件绑定,导致SQL的逻辑运算顺序出错。原代码里的查询:

SELECT * FROM passenger_records 
WHERE pas_depdate='$date1' AND pas_air='$air' AND pas_frmcity='$from' AND pas_tocity='$to' 
AND (pas1_seat='$seat' OR pas2_seat='$seat') OR (pas3_seat='$seat' OR pas4_seat='$seat')

因为OR的优先级低于AND,实际执行逻辑变成了:(航班日期条件 AND 前两个座位条件) OR 后两个座位条件——这会导致只要任何一个座位(不管属于哪个航班/日期)被占用,就会返回记录,错误地判定当前座位已被占。

问题2:全局变量导致的座位状态残留

你用了全局变量$seat,每次调用f1()时,这个变量会保留上一次分配的座位值,而不是从1A开始重新检查。比如第一次分配1A后,第二次调用f1()时$seat还是1A,检查到已被占用就跳到1B;第三次调用时$seat是1B,检查到被占用后,你的循环逻辑会错误地跳到下一排的2A,而不是继续检查1C。


修复后的完整代码

<?php
function f1() {
    require 'connection.php';
    // 从SESSION获取航班核心参数
    $from = $_SESSION['fro'];
    $to = $_SESSION['to'];
    $date1 = $_SESSION['dep'];
    $air = $_SESSION['airl'];
    
    $rowNumbers = range(1, 5); // 假设头等舱最多5排,可按需调整
    $seatColumns = array("A", "B", "C", "D");
    
    // 从第一排第一个座位开始,依次检查是否被占用
    foreach ($rowNumbers as $row) {
        foreach ($seatColumns as $col) {
            $currentSeat = $row . $col;
            // 修正SQL逻辑:所有座位检查用一个括号包裹,确保和航班日期条件是AND关系
            $checkQuery = "SELECT * FROM passenger_records 
                          WHERE pas_depdate='$date1' 
                            AND pas_air='$air' 
                            AND pas_frmcity='$from' 
                            AND pas_tocity='$to' 
                            AND (pas1_seat='$currentSeat' OR pas2_seat='$currentSeat' OR pas3_seat='$currentSeat' OR pas4_seat='$currentSeat')";
            
            $result = $conn->query($checkQuery);
            // 找到第一个未被占用的座位,直接返回
            if ($result->num_rows === 0) {
                return $currentSeat;
            }
        }
    }
    
    // 如果所有座位都被占用,返回空字符串
    return "";
}

if ($cls == "First Class") {
    // 为每个乘客分配座位,每次调用f1都会从头检查
    if (!empty($pas1)) {
        $seat1 = f1();
        echo $seat1 . "<BR>";
        $updateSql = "UPDATE `passenger_records` SET `pas1_seat` = '{$seat1}' WHERE `passenger_records`.`pas_id` = '$id'";
        $conn->query($updateSql);
    }
    if (!empty($pas2)) {
        $seat2 = f1();
        echo $seat2 . "<BR>";
        $updateSql = "UPDATE passenger_records SET pas2_seat = '{$seat2}' WHERE passenger_records.pas_id = '$id'";
        $conn->query($updateSql);
    }
    if (!empty($pas3)) {
        $seat3 = f1();
        echo $seat3 . "<BR>";
        $updateSql = "UPDATE passenger_records SET pas3_seat = '{$seat3}' WHERE passenger_records.pas_id = '$id'";
        $conn->query($updateSql);
    }
    if (!empty($pas4)) {
        $seat4 = f1();
        echo $seat4 . "<BR>";
        $updateSql = "UPDATE `passenger_records` SET `pas4_seat` = '{$seat4}' WHERE `passenger_records`.`pas_id` = '$id'";
        $conn->query($updateSql);
    }
}
?>

关键修改说明

  1. 移除全局变量:用局部变量$currentSeat替代全局$seat,每次调用f1()都会从1A开始重新遍历,彻底解决状态残留问题。
  2. 修正SQL逻辑:将所有座位检查条件用一个括号包裹,确保只检查当前航班/日期下的座位占用情况,避免误判。
  3. 简化遍历逻辑:用嵌套foreach循环替代原有的while+for循环,逻辑更直观,从第一排第一个座位开始,找到第一个空座就返回。
  4. 规范空值检查:用!empty()替代!$pas1=="",写法更严谨。

现在测试的话,不管是首次还是其他日期预订4人,都会依次分配1A、1B、1C、1D,完美符合你的预期!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:42:04