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

如何在PHP表单中同时传递城市ID与名称至结果页?

问题描述

我正在开发一个美国城市间旅行网站,用户在表单中选择两个城市后,结果页需要显示所选城市名称及对应旅行选项信息。数据库包含Cities、Route(桥接表)、Options三张表,目前表单已能通过POST传递城市ID到result.php用于查询路线,但无法同时获取城市名称——我需要ID来查询桥接表数据,同时要在页面显示城市名称。现有代码如下:

表单页代码

<form method="post" action="result.php">
  <select name="departOption">
  <?php
  $query = "SELECT * FROM cities;"; 
  $result = mysqli_query($conn, $query); 
  if (mysqli_num_rows($result) > 0) { 
      while($row = mysqli_fetch_assoc($result)) { 
        $CityNumber = $row["No"];
        $CityName = $row["City"];
        ?>
          <option value="<?php echo $CityNumber ?>"><?php echo $CityName ?> </option>
          <?php
      } 
  } else { 
      echo "-"; 
  } ?>
  </select>
  <select name="arriveOption">
  <?php
  $query = "SELECT * FROM cities;"; 
  $result = mysqli_query($conn, $query);
  if (mysqli_num_rows($result) > 0) { 
      while($row = mysqli_fetch_assoc($result)) { 
        $CityNumber = $row["No"];
        $CityName = $row["City"];
        ?>
          <option value="<?php echo $CityNumber ?>"><?php echo $CityName ?> </option>
          <?php
      } 
  } else { 
      echo "-"; 
  } ?>
  </select>
  <input type="submit" value="Submit the form"/>
</form>

result.php代码

<?php
  $option1 = isset($_POST['departOption']) ? $_POST['departOption'] : false;
  if ($option1) {
      echo "<p>".($_POST['departOption']) ."</p>";
  } else {
    echo "Depart Option is required";
    exit; 
  }
  $option2 = isset($_POST['arriveOption']) ? $_POST['arriveOption'] : false;
  if ($option2) {
      echo "<p>".($_POST['arriveOption']) ."</p>";
  } else {
    echo "Arrive Option is required";
    exit; 
  }
$query = "SELECT * FROM `route`,options  WHERE route.Depart_City = " . $option1 . " AND route.Arrive_City = " . $option2 . " AND route.Information = options.No";
$result = mysqli_query($conn, $query); 
if (mysqli_num_rows($result) > 0) { 
    while($row = mysqli_fetch_assoc($result)) { 
      $Option_Description = $row["Desc"];
      ?>
        <p> <?php echo $Option_Description ?></p>
      <?php
    } 
} else { 
    echo "No options available."; 
} ?>

解决方案

方案1:通过ID反向查询城市名称(推荐)

利用提交的城市ID,在result.php中查询Cities表获取对应名称,这种方式符合数据库设计规范,且避免前端传递数据被篡改的风险。

修改后的result.php代码:

<?php
// 获取提交的城市ID
$departId = isset($_POST['departOption']) ? $_POST['departOption'] : false;
$arriveId = isset($_POST['arriveOption']) ? $_POST['arriveOption'] : false;

// 校验必填项
if (!$departId) {
    echo "Depart Option is required";
    exit;
}
if (!$arriveId) {
    echo "Arrive Option is required";
    exit;
}

// 查询出发城市名称(使用预处理语句防SQL注入)
$cityStmt = mysqli_prepare($conn, "SELECT City FROM cities WHERE No = ?");
mysqli_stmt_bind_param($cityStmt, "i", $departId);
mysqli_stmt_execute($cityStmt);
$departRow = mysqli_fetch_assoc(mysqli_stmt_get_result($cityStmt));
$departCity = $departRow['City'];

// 查询到达城市名称
mysqli_stmt_bind_param($cityStmt, "i", $arriveId);
mysqli_stmt_execute($cityStmt);
$arriveRow = mysqli_fetch_assoc(mysqli_stmt_get_result($cityStmt));
$arriveCity = $arriveRow['City'];

// 显示城市名称
echo "<p>出发城市:{$departCity}</p>";
echo "<p>到达城市:{$arriveCity}</p>";

// 查询路线及选项信息(改用JOIN语法+预处理语句)
$routeStmt = mysqli_prepare($conn, "
    SELECT options.Desc 
    FROM `route` 
    JOIN options ON route.Information = options.No 
    WHERE route.Depart_City = ? AND route.Arrive_City = ?
");
mysqli_stmt_bind_param($routeStmt, "ii", $departId, $arriveId);
mysqli_stmt_execute($routeStmt);
$result = mysqli_stmt_get_result($routeStmt);

if (mysqli_num_rows($result) > 0) { 
    while($row = mysqli_fetch_assoc($result)) { 
        echo "<p>{$row['Desc']}</p>";
    } 
} else { 
    echo "No options available."; 
} 

// 关闭语句连接
mysqli_stmt_close($cityStmt);
mysqli_stmt_close($routeStmt);
?>

方案2:在表单选项中传递ID+名称组合

如果不想额外查询数据库,可以将option的value设置为ID与名称的组合(用分隔符拆分),在result.php中拆分后使用。

修改表单页的option代码

<option value="<?php echo $CityNumber . ',' . urlencode($CityName); ?>"><?php echo $CityName; ?></option>

(使用urlencode处理城市名称,避免特殊字符导致拆分错误)

修改后的result.php代码

<?php
$departValue = isset($_POST['departOption']) ? $_POST['departOption'] : false;
$arriveValue = isset($_POST['arriveOption']) ? $_POST['arriveOption'] : false;

if (!$departValue) {
    echo "Depart Option is required";
    exit;
}
if (!$arriveValue) {
    echo "Arrive Option is required";
    exit;
}

// 拆分出发城市ID和名称
list($departId, $departCity) = explode(',', $departValue);
$departCity = urldecode($departCity);

// 拆分到达城市ID和名称
list($arriveId, $arriveCity) = explode(',', $arriveValue);
$arriveCity = urldecode($arriveCity);

// 显示城市名称
echo "<p>出发城市:{$departCity}</p>";
echo "<p>到达城市:{$arriveCity}</p>";

// 查询路线信息(使用预处理语句防注入)
$stmt = mysqli_prepare($conn, "
    SELECT options.Desc 
    FROM `route` 
    JOIN options ON route.Information = options.No 
    WHERE route.Depart_City = ? AND route.Arrive_City = ?
");
mysqli_stmt_bind_param($stmt, "ii", $departId, $arriveId);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

if (mysqli_num_rows($result) > 0) { 
    while($row = mysqli_fetch_assoc($result)) { 
        echo "<p>{$row['Desc']}</p>";
    } 
} else { 
    echo "No options available."; 
} 
?>

重要提示

原代码直接将POST参数拼接进SQL语句,存在严重SQL注入风险,上述两种方案均使用**预处理语句(prepared statements)**修复了该漏洞,这是PHP操作数据库的必备安全规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:08:23