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

PHP开发工作流审批系统:点击表单按钮仅显示最后一条数据的问题求助

问题:点击审批按钮始终显示最后一条表单的详情

我是PHP新手,正在开发一套工作流审批网站:用户提交表单后数据存入MySQL,approve.php从数据库拉取数据展示表单列表(包含FormID、姓名、日期等),每行的状态按钮点击后应该跳转到approveForm.php展示对应表单的详情。

但现在遇到了异常:不管点击哪一行的按钮,approveForm.php都只会显示列表里最后一条数据(FormID=27)的详情,求各位帮忙解决这个问题!


我的代码

approve.php

<?php session_start(); error_reporting(0); 
$host = "localhost"; 
$dbUsername = "root"; 
$dbPassword = ""; 
$dbName = "it_login"; 
$conn = new mysqli($host, $dbUsername, $dbPassword, $dbName); 
$sql = "SELECT * FROM supportformuser WHERE Name = 'Admin12' ORDER BY Form_ID ASC "; 
$results = mysqli_query($conn, $sql); 

if (isset($_SESSION['id']) && isset($_SESSION['User_ID'])) { 
    // session timeout (time calculated in seconds) 
    if (time() - $_SESSION["login_time_stamp"] > 86400) { 
        session_unset(); 
        session_destroy(); 
        header("Location:index.php"); 
        exit(); 
    } 
?>
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="approve.css">
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="approve.js"></script>
</head>
<body>
<div class=all>
<h1>Approval Process</h1>
<div class="tbl-header">
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th style="width: 10%;">Form ID</th>
<th style="width: 15%;">Requested By</th>
<th style="width: 10%;">Date </th>
<th style="width: 20%;">Form Type</th>
<th style="width: 35%;">Reason Of Request</th>
<th style="width: 10%">Status</th>
</tr>
</thead>
</table>
</div>
<form method="POST" class="tbl-content">
<table cellpadding="0" cellspacing="0">
<tbody>
<?php while ($rows = mysqli_fetch_assoc($results)) { ?>
<tr height="100px">
<td style="width: 10%;" id="FormID" value="<?php echo $rows['Form_ID']; ?>"><?php echo $rows['Form_ID']; ?></td>
<td style="width: 15%;"><?php echo $rows['Name']; ?></td>
<td style="width: 10%;"><?php echo $rows['Date']; ?></td>
<td style="width: 20%;"><?php echo $rows['Form_Type']; ?></td>
<td style="text-align: justify; width:35%;" class="show-read-more"><?php echo $rows['Reason_Of_Request']; ?></td>
<td style="width: 10%;">
<button type="submit" name="status" value=" <?php echo $rows['HOD_Status']; ?>"><?php echo $rows['HOD_Status']; ?></button>
</td>
</tr>
<?php if(isset($_POST['status'])) { 
    // session_unset(); 
    unset($_SESSION['FormID']); 
    $_SESSION['FormID'] = $rows['Form_ID']; 
    header("Location: approveForm.php"); 
} } ?>
</tbody>
</table>
</form>
<div style="text-align:center;" class="logout" onclick="location.href = 'logout.php'">
<button id="logout">LOG OUT</button>
</div>
</div>
</body>
</html>
<?php } else { 
    header("Location: index.php"); 
    exit(); 
} ?>

approveForm.php

<?php session_start(); 
$host = "localhost"; 
$dbUsername = "root"; 
$dbPassword = ""; 
$dbName = "it_login"; 
$conn = new mysqli($host, $dbUsername, $dbPassword, $dbName); 

$formID = $_SESSION['FormID']; 
$sql = "SELECT * FROM supportformuser WHERE Form_ID = '$formID' "; 
$sql1 = "SELECT * FROM request_form WHERE Form_ID = '$formID' "; 
$sql2 = "SELECT * FROM application_support_form WHERE Form_ID = '$formID' "; 

$results = mysqli_query($conn, $sql); 
$results1 = mysqli_query($conn, $sql1); 
$results2 = mysqli_query($conn, $sql2); 

if (isset($_SESSION['id']) && isset($_SESSION['User_ID'])) { 
    // session timeout (time calculated in seconds) 
    if (time() - $_SESSION["login_time_stamp"] > 86400) { 
        session_unset(); 
        session_destroy(); 
        header("Location:index.php"); 
        exit(); 
    } 
?>
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="approveForm.css">
</head>
<body>
<div class="all">
<h1>Workflow Approval Process</h1>
<div class="tbl-header">
<table cellpadding="0" cellspacing="0">
<?php while ($rows = mysqli_fetch_assoc($results)) { ?>
<thead>
<tr><th>Form ID</th><td><?php echo $rows['Form_ID'] ?></td></tr>
<tr><th>User ID</th><td><?php echo $rows['User_ID'] ?></td></tr>
<tr><th>Company</th><td><?php echo $rows['Company'] ?></td></tr>
<tr><th>Date</th><td><?php echo $rows['Date'] ?></td></tr>
<tr><th>Name</th><td><?php echo $rows['Name'] ?></td></tr>
<tr><th>Department</th><td><?php echo $rows['Department'] ?></td></tr>
<tr><th>Type of Form</th><td><?php echo $rows['Form_Type'] ?></td></tr>
<?php while ($rows = mysqli_fetch_assoc($results1)) { ?>
<tr><th>Account Login & Access Right (Staff)</th><td><?php echo $rows['Staff_Status'] ?></td></tr>
<tr><th>Account Login & Access Right (Login ID)</th><td><?php echo $rows['Account'] ?></td></tr>
<tr><th>Access Right Requirement</th><td><?php echo $rows['Access_Right_Requirement'] ?></td></tr>
<tr><th>IT Comment (For IT Technician Only)</th><td><?php echo $rows['IT_Comment_Account_Login_Access_Right'] ?></td></tr>
<tr><th>Support Request (Software)</th><td><?php echo $rows['Software'] ?></td></tr>
<tr><th>Support Request (Software) Requirement</th><td><?php echo $rows['Software_Requirement'] ?></td></tr>
<tr><th>IT Comment (For IT Technician only)</th><td><?php echo $rows['IT_Comment_Software_Requirement'] ?></td></tr>
<tr><th>Support Request (Hardware)</th><td><?php echo $rows['Hardware'] ?></td></tr>
<tr><th>Support Request (Hardware) Requirement</th><td><?php echo $rows['Hardware_Requirement'] ?></td></tr>
<tr><th>IT Comment (For IT Technician only)</th><td><?php echo $rows['IT_Comment_Hardware_Requirement'] ?></td></tr>
<tr><th>Support Request (Tech Support Request)</th><td><?php echo $rows['Tech_Support_Request'] ?></td></tr>
<tr><th>Support Request (Job) Requirement</th><td><?php echo $rows['Job_Requirement'] ?></td></tr>
<tr><th>IT Comment (For IT Technician only)</th><td><?php echo $rows['IT_Comment_Job_Requirement'] ?></td></tr>
<?php } ?>
<?php while ($rows = mysqli_fetch_assoc($results2)) { ?>
<tr><th>Application Support Form (Software)</th><td><?php echo $rows['Software'] ?></td></tr>
<tr><th>Application Support Form (Software) Remark</th><td><?php echo $rows['Software_Remark'] ?></td></tr>
<tr><th>IT Comment (For IT Technician only)</th><td><?php echo $rows['IT_Comment_Software'] ?></td></tr>
<tr><th>Application Support Form (Task)</th><td><?php echo $rows['Task'] ?></td></tr>
<tr><th>Application Support Form (Task) Remark</th><td><?php echo $rows['Remark_For_Item2'] ?></td></tr>
<tr><th>IT Comment (For IT Technician only)</th><td><?php echo $rows['IT_Comment_Task'] ?></td></tr>
<?php } ?>
</thead>
<?php } ?>
</table>
</div>
</div>
</body>
</html>
<?php } else { 
    header("Location: index.php"); 
    exit(); 
} ?>

问题根源

  1. 表单结构错误:所有行的按钮都放在同一个<form>标签里,提交时无法区分是哪一行的按钮触发的请求。
  2. 逻辑位置错误:把$_POST['status']的判断和$_SESSION['FormID']的赋值放在了while循环内部。页面加载时循环会遍历所有记录,最后一次循环会把$_SESSION['FormID']覆盖成最后一条记录的ID;且POST请求触发时,循环里的header跳转会执行多次,最终生效的是最后一次赋值。
  3. 安全隐患:直接把变量拼进SQL语句,存在严重的SQL注入风险。

修复方案

我推荐用GET方式传递FormID(查看详情用GET更合理),同时重构表单结构,给每行单独做一个小表单,或者直接用链接按钮。

步骤1:修改approve.php

  • 删除全局的<form>标签,给每行的按钮单独创建表单,或者用带参数的链接。
  • 删除循环内的POST处理逻辑。

修改后的核心表格部分:

<tbody>
<?php while ($rows = mysqli_fetch_assoc($results)) { ?>
<tr height="100px">
<td style="width: 10%;"><?php echo $rows['Form_ID']; ?></td>
<td style="width: 15%;"><?php echo $rows['Name']; ?></td>
<td style="width: 10%;"><?php echo $rows['Date']; ?></td>
<td style="width: 20%;"><?php echo $rows['Form_Type']; ?></td>
<td style="text-align: justify; width:35%;" class="show-read-more"><?php echo $rows['Reason_Of_Request']; ?></td>
<td style="width: 10%;">
<!-- 方案1:用GET表单传递参数 -->
<form method="GET" action="approveForm.php" style="margin:0;">
    <input type="hidden" name="formID" value="<?php echo $rows['Form_ID']; ?>">
    <button type="submit"><?php echo $rows['HOD_Status']; ?></button>
</form>

<!-- 方案2:直接用链接按钮(更简洁) -->
<!-- <a href="approveForm.php?formID=<?php echo $rows['Form_ID']; ?>" style="display:inline-block; padding:8px 16px; background:#ddd; text-decoration:none; border-radius:4px; color:#000;"><?php echo $rows['HOD_Status']; ?></a> -->
</td>
</tr>
<?php } ?>
</tbody>

步骤2:修改approveForm.php

  • 从$_GET['formID']获取参数,替代SESSION方式。
  • 使用预处理语句防止SQL注入。

修改后的核心查询部分:

<?php session_start(); 
$host = "localhost"; 
$dbUsername = "root"; 
$dbPassword = ""; 
$dbName = "it_login"; 
$conn = new mysqli($host, $dbUsername, $dbPassword, $dbName); 

// 校验参数合法性
if(!isset($_GET['formID']) || !is_numeric($_GET['formID'])){
    header("Location: approve.php");
    exit();
}
$formID = $_GET['formID']; 

// 预处理查询,避免SQL注入
$sql = "SELECT * FROM supportformuser WHERE Form_ID = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $formID);
$stmt->execute();
$results = $stmt->get_result();

$sql1 = "SELECT * FROM request_form WHERE Form_ID = ?";
$stmt1 = $conn->prepare($sql1);
$stmt1->bind_param("i", $formID);
$stmt1->execute();
$results1 = $stmt1->get_result();

$sql2 = "SELECT * FROM application_support_form WHERE Form_ID = ?";
$stmt2 = $conn->prepare($sql2);
$stmt2->bind_param("i", $formID);
$stmt2->execute();
$results2 = $stmt2->get_result();

// 后续HTML部分保持不变...
?>

这样修改后,点击每行按钮会传递对应FormID,就能正确展示对应表单的详情,同时解决了SQL注入的安全问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:12:31