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

PHP表单仅保存表格最后一行数据的问题排查

问题原因分析

你遇到的核心问题是表单控件的名称重复导致提交值被覆盖:所有下拉框的name属性都是相同的(比如Dz_M),当浏览器提交表单时,同名的控件只会保留最后一个的值,所以后端拿到的自然是表格最后一行的选择结果。

修复步骤

1. 修改new_tear.php的表单控件

需要把每个下拉框的name改成带用户唯一标识的数组格式,同时传递每个用户的唯一ID(假设你的ProfileTable有id字段),这样后端能准确对应每个用户的选择:

<?php 
$sqlT1 = "SELECT * FROM ProfileTable WHERE dept = 'T1'"; 
$queryT1 = mysqli_query($conn, $sqlT1); 
if (!$queryT1) { die ('SQL Error: ' . mysqli_error($conn)); } 
?> 
<form action="tear_done.php" method="post"> 
<table> 
<?php 
$no = 1; 
while ($row = mysqli_fetch_array($queryT1)) { 
    $userId = $row['id']; // 取用户唯一ID,用来关联选择值
    echo '<tr> 
    <td>'.$no.'</td> 
    <td>'.$row['name'].'</td> 
    <!-- 隐藏字段传递用户ID -->
    <input type="hidden" name="user_ids[]" value="'.$userId.'">
    <td><select id="Dz_M_'.$userId.'" name="Dz_M['.$userId.']"> 
    <option value="4pm">4pm</option> 
    <option value="8am">8am</option> 
    <option value="Rest">Rest</option> 
    </select><br> 
    </td> 
    <td><select id="Dz_T_'.$userId.'" name="Dz_T['.$userId.']"> 
    <option value="4pm">4pm</option> 
    <option value="8am">8am</option> 
    <option value="Rest">Rest</option> 
    </select><br> 
    </td> 
    <td><select id="Dz_W_'.$userId.'" name="Dz_W['.$userId.']"> 
    <option value="4pm">4pm</option> 
    <option value="8am">8am</option> 
    <option value="Rest">Rest</option> 
    </select><br> 
    </td> 
    <td><select id="Dz_F_'.$userId.'" name="Dz_F['.$userId.']"> 
    <option value="4pm">4pm</option> 
    <option value="8am">8am</option> 
    <option value="Rest">Rest</option> 
    </select><br> 
    </td> 
    <td><select id="Dz_S_'.$userId.'" name="Dz_S['.$userId.']"> 
    <option value="4pm">4pm</option> 
    <option value="8am">8am</option> 
    <option value="Rest">Rest</option> 
    </select><br> 
    </td> 
    </tr>'; 
    $no++; 
}?> 
</table> 
<br> 
<button value="save" type="submit" name="save">Save Tear</button> 
</form>

这里做了两个关键修改:

  • 给每个下拉框的name加上用户ID作为数组键(比如Dz_M[123]),确保每个用户的选择不会被覆盖
  • 添加隐藏字段user_ids[],传递所有需要处理的用户ID

2. 修改tear_done.php的处理逻辑

不需要再次查询ProfileTable,直接遍历提交的用户ID数组,取出对应选择值插入数据库,同时必须使用预处理语句防止SQL注入(你的原代码存在严重的注入风险):

<?php
if(isset($_POST['save'])){
    // 获取提交的所有数据
    $userIds = $_POST['user_ids'];
    $dzM = $_POST['Dz_M'];
    $dzT = $_POST['Dz_T'];
    $dzW = $_POST['Dz_W'];
    $dzF = $_POST['Dz_F'];
    $dzS = $_POST['Dz_S'];

    // 预处理SQL,避免注入
    $sql = "INSERT INTO TearTable (name, Mdy, Tdy, Wdy, Fdy, Sdy, dept) 
            SELECT name, ?, ?, ?, ?, ?, dept FROM ProfileTable WHERE id = ?";
    $stmt = mysqli_prepare($conn, $sql);

    foreach($userIds as $id){
        // 绑定参数到预处理语句
        mysqli_stmt_bind_param($stmt, 'sssssi', $dzM[$id], $dzT[$id], $dzW[$id], $dzF[$id], $dzS[$id], $id);
        // 执行插入
        mysqli_stmt_execute($stmt);

        // 测试输出(可以删除)
        echo "处理用户ID: {$id}<br>";
        echo "SQL参数: {$dzM[$id]}, {$dzT[$id]}, {$dzW[$id]}, {$dzF[$id]}, {$dzS[$id]}<br><br>";
    }

    // 清理资源
    mysqli_stmt_close($stmt);
}
?>
额外注意事项
  • 如果你的ProfileTable没有id字段,可以用name作为关联键,但要确保姓名不会重复
  • 表单中每个元素的id属性也要唯一(比如Dz_M_'.$userId.'),避免DOM元素ID冲突
  • 永远不要直接把用户输入拼接到SQL语句中,预处理语句是必须的安全措施

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:02:51