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

PHP获取MySQL选中行数据问题:休假审批邮件内容错误

解决选中行数据获取错误的问题

你遇到的核心问题很明确:循环渲染表单时,所有行的隐藏字段(worker_name、Name等)都用了相同的name属性。当表单提交后,PHP只会保留最后一行的这些字段值,完全忽略了你实际勾选的行。下面给你两种可行的解决方案,其中第二种更推荐(安全性更高):

方案1:将隐藏字段改为与ID关联的数组

修改表单循环部分的隐藏字段,让它们的name包含当前行的ID,这样提交后就能精准对应到每个勾选的条目:

<tr>
<td align="center">
<input type="checkbox" name="checked_id[]" class="checkbox" value="<?php echo $row['ID']; ?>"/>
<!-- 把隐藏字段的name改成带ID的数组,关联当前行 -->
<input type="hidden" name="worker_name[<?php echo $row['ID']; ?>]" value="<?php echo $row['worker_name']; ?>"/>
<input type="hidden" name="Name[<?php echo $row['ID']; ?>]" value="<?php echo $row['Name']; ?>"/>
<input type="hidden" name="FirstDayOff[<?php echo $row['ID']; ?>]" value="<?php echo $row['FirstDayOff']; ?>"/>
<input type="hidden" name="FirstDayBack[<?php echo $row['ID']; ?>]" value="<?php echo $row['FirstDayBack']; ?>"/>
</td>
<!-- 其他列的渲染代码保持不变 -->
</tr>

然后在action-approve.php里,循环时根据当前ID从数组中取出对应的值:

<?php 
session_start(); 
include_once('dbConfig.php'); 

if(isset($_POST['bulk_approve_submit'])){ 
    $idArr = $_POST['checked_id']; 
    foreach($idArr as $id){ 
        // 更新状态
        mysqli_query($conn,"UPDATE Request_off SET Status='Approved' WHERE ID=".$id); 
        
        // 从关联数组中获取当前ID对应的字段值
        $worker_name = $_POST['worker_name'][$id]; 
        $Name = $_POST['Name'][$id]; 
        $FirstDayOff = $_POST['FirstDayOff'][$id]; 
        $FirstDayBack = $_POST['FirstDayBack'][$id]; 
        
        // 邮件发送逻辑不变
        $to = $worker_name.'@somewhere.com, request-off@somewhere.com'; 
        $subject = 'APPROVED: Time off request for '.$Name; 
        $message = 'Dear '.$Name.','. "\r\n\n" .'Your time off request from '.$FirstDayOff.' to '.$FirstDayBack.' has been approved!'. "\r\n\n" .'Note: Please keep a copy of this email for your records.'; 
        $headers = 'From: request-off@somewhere.com'; 
        mail($to, $subject, $message, $headers); 
    } 
    $_SESSION['success_msg'] = 'Request has been approved successfully.'; 
    header("Location: Request_off-admin.php?Status=Pending"); 
} 
?>

方案2:根据选中ID从数据库重新查询数据(更推荐)

前端只传递选中的ID,后端根据ID去数据库查询对应的用户和休假信息。这种方式可以避免前端篡改隐藏字段的值,安全性更高,也更符合后端数据校验的最佳实践:

第一步:简化表单,只保留勾选框

循环里不需要任何隐藏字段,只保留复选框即可:

<tr>
<td align="center">
<input type="checkbox" name="checked_id[]" class="checkbox" value="<?php echo $row['ID']; ?>"/>
</td>
<!-- 其他列的渲染代码保持不变 -->
</tr>

第二步:修改action-approve.php,查询对应数据

<?php 
session_start(); 
include_once('dbConfig.php'); 

if(isset($_POST['bulk_approve_submit'])){ 
    $idArr = $_POST['checked_id']; 
    foreach($idArr as $id){ 
        // 先更新状态
        mysqli_query($conn,"UPDATE Request_off SET Status='Approved' WHERE ID=".$id); 
        
        // 根据ID查询当前行的完整数据
        $result = mysqli_query($conn,"SELECT worker_name, Name, FirstDayOff, FirstDayBack FROM Request_off WHERE ID=".$id); 
        $row = mysqli_fetch_assoc($result); 
        
        // 从查询结果中获取字段值
        $worker_name = $row['worker_name']; 
        $Name = $row['Name']; 
        $FirstDayOff = $row['FirstDayOff']; 
        $FirstDayBack = $row['FirstDayBack']; 
        
        // 邮件发送逻辑不变
        $to = $worker_name.'@somewhere.com, request-off@somewhere.com'; 
        $subject = 'APPROVED: Time off request for '.$Name; 
        $message = 'Dear '.$Name.','. "\r\n\n" .'Your time off request from '.$FirstDayOff.' to '.$FirstDayBack.' has been approved!'. "\r\n\n" .'Note: Please keep a copy of this email for your records.'; 
        $headers = 'From: request-off@somewhere.com'; 
        mail($to, $subject, $message, $headers); 
    } 
    $_SESSION['success_msg'] = 'Request has been approved successfully.'; 
    header("Location: Request_off-admin.php?Status=Pending"); 
} 
?>

额外提醒:为了避免SQL注入风险,建议使用预处理语句来执行查询和更新,示例如下:

// 更新操作的预处理示例
$stmt = $conn->prepare("UPDATE Request_off SET Status='Approved' WHERE ID=?");
$stmt->bind_param("i", $id); // "i"表示参数为整数类型
$stmt->execute();
$stmt->close();

针对你提到的「用一个复选框选中整行」的优化

如果你想实现点击整行任意位置就能勾选/取消对应的复选框,可以用JavaScript快速实现:

<!-- 给每行的tr添加一个类名,比如row-item,给复选框添加类名row-checkbox -->
<tr class="row-item">
<td align="center">
<input type="checkbox" name="checked_id[]" class="checkbox row-checkbox" value="<?php echo $row['ID']; ?>"/>
</td>
<!-- 其他列代码不变 -->
</tr>

<script>
// 给每行绑定点击事件
document.querySelectorAll('.row-item').forEach(row => {
    row.addEventListener('click', function(e){
        // 如果点击的不是复选框本身,就切换复选框状态
        if(!e.target.classList.contains('row-checkbox')){
            const checkbox = this.querySelector('.row-checkbox');
            checkbox.checked = !checkbox.checked;
        }
    });
});
</script>

这样用户点击整行的任何地方,都能触发复选框的勾选状态切换,体验会更流畅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:35:06