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

表单数据批量保存至多选中数据库表的问题求助

问题描述

我希望通过勾选表单中的复选框,将表单数据一次性保存到数据库的多个表中。目前表单里只有4个复选框,后续会增加到15个。

当前代码在只选中一个表时能正常保存数据,但同时选中多个表时,数据总是仅保存到最后选中的表,之前选中的表会被跳过,求解决。

原表单代码:

<form action="process.php" method="post">
   <label for="first">Number:</label>
   <input type="text" name="number" id="first">

   <label for="second">Date:</label>
   <input type="text" name="date" id="second">

   <label for="type">Type:</label>
      <select name="ctype" id="type">
      <option value="Photo">Photo</option>
      <option value="Video">Video</option>
   </select>

   <input type="hidden" name="table1" value="no">
   <input type="hidden" name="table2" value="no">
   <input type="hidden" name="table3" value="no">
   <input type="hidden" name="table4" value="no">

   <input type="checkbox" name="table1" value="yes">Table1
   <input type="checkbox" name="table2" value="yes">Table2
   <input type="checkbox" name="table3" value="yes">Table3
   <input type="checkbox" name="table4" value="yes">Table4

   <input type="submit" value="Submit">
</form>

原PHP处理代码:

<?php
    $number = $_REQUEST['number'];
    $date = $_REQUEST['date'];
    $ctype = $_REQUEST['ctype'];
    $chck1 = $_REQUEST['table1'];
    $chck2 = $_REQUEST['table2'];
    $chck3 = $_REQUEST['table3'];
    $chck4 = $_REQUEST['table4'];

    if($_POST['table1'] === 'yes'){
    $sql = "INSERT INTO table1 VALUES ('$number', '$date', '$ctype')";}
    else{
    echo "ERROR: UCHECKED 1";
    }

    if($_POST['table2'] === 'yes'){
    $sql = "INSERT INTO table2 VALUES ('$number', '$date', '$ctype')";}
    else{
    echo "ERROR: UCHECKED 2";
    }

    if($_POST['table3'] === 'yes'){
    $sql = "INSERT INTO table3 VALUES ('$number', '$date', '$ctype')";}
    else{
    echo "ERROR: UCHECKED 3";
    }

    if($_POST['table4'] === 'yes'){
    $sql = "INSERT INTO table4 VALUES ('$number', '$date', '$ctype')";}
    else{
    echo "ERROR: UCHECKED 4";
    }

    if(mysqli_query($conn, $sql)){
    echo "<h3>Data stored in a database."; 

    echo nl2br("
$number
 $date
 "
    . "$ctype");
    } else{
    echo "ERROR $sql. "
    . mysqli_error($conn);
    }

    mysqli_close($conn);
?>

问题根源

你代码的核心问题是:所有if分支只是在给$sql变量赋值,最后只执行了一次mysqli_query——前面选中的表对应的SQL语句会被后面的覆盖,自然只有最后一个表能插入成功。

另外,直接把用户输入拼接到SQL语句里存在严重的SQL注入风险,这是必须修复的安全漏洞。

修复方案

1. 表单优化(适配后续15个表的扩展)

把复选框改成数组形式,不用再写隐藏域,未勾选的表不会被提交到后端:

<form action="process.php" method="post">
   <label for="first">Number:</label>
   <input type="text" name="number" id="first">

   <label for="second">Date:</label>
   <input type="text" name="date" id="second">

   <label for="type">Type:</label>
      <select name="ctype" id="type">
      <option value="Photo">Photo</option>
      <option value="Video">Video</option>
   </select>

   <input type="checkbox" name="target_tables[]" value="table1">Table1
   <input type="checkbox" name="target_tables[]" value="table2">Table2
   <input type="checkbox" name="target_tables[]" value="table3">Table3
   <input type="checkbox" name="target_tables[]" value="table4">Table4

   <input type="submit" value="Submit">
</form>

2. PHP处理代码(安全+高效)

用循环处理选中的表,同时使用预处理语句防止SQL注入:

<?php
// 假设$conn是已经建立好的数据库连接(请确保连接代码正确)
$number = $_POST['number'] ?? '';
$date = $_POST['date'] ?? '';
$ctype = $_POST['ctype'] ?? '';
$targetTables = $_POST['target_tables'] ?? [];

// 基础输入验证
if(empty($number) || empty($date) || empty($ctype) || empty($targetTables)){
    echo "请填写完整信息并至少选择一个表";
    exit;
}

// 允许的表列表,后续新增表直接在这里添加即可
$allowedTables = ['table1', 'table2', 'table3', 'table4'];

foreach($targetTables as $table){
    // 验证表名合法性,防止恶意注入
    if(!in_array($table, $allowedTables)){
        continue;
    }

    // 预处理语句(表名不能用参数绑定,所以先验证再替换)
    $sql = "INSERT INTO {$table} VALUES (?, ?, ?)";
    $stmt = mysqli_prepare($conn, $sql);
    // 绑定参数,"sss"表示三个字符串类型的参数
    mysqli_stmt_bind_param($stmt, "sss", $number, $date, $ctype);

    // 执行插入
    if(mysqli_stmt_execute($stmt)){
        echo "<p>数据已成功保存到 {$table}</p>";
    } else {
        echo "<p>保存到 {$table} 失败:" . mysqli_error($conn) . "</p>";
    }

    mysqli_stmt_close($stmt);
}

mysqli_close($conn);
?>

核心改进

  • 每个选中的表单独执行插入操作,不再覆盖SQL语句
  • 用预处理语句+参数绑定彻底避免SQL注入
  • 数组形式处理复选框,后续新增表只需修改allowedTables数组和表单,不用写大量重复的if分支
  • 增加输入验证和表名校验,提升代码安全性和健壮性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 22:50:54