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(); } ?>
问题根源
- 表单结构错误:所有行的按钮都放在同一个
<form>标签里,提交时无法区分是哪一行的按钮触发的请求。 - 逻辑位置错误:把
$_POST['status']的判断和$_SESSION['FormID']的赋值放在了while循环内部。页面加载时循环会遍历所有记录,最后一次循环会把$_SESSION['FormID']覆盖成最后一条记录的ID;且POST请求触发时,循环里的header跳转会执行多次,最终生效的是最后一次赋值。 - 安全隐患:直接把变量拼进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
相关产品推荐
相关产品推荐

