PHP表单下拉框无法更新第一条数据库记录求助
问题:首条记录下拉框修改状态无响应
我正在开发一个PHP表单,从数据库加载数据,每条记录对应一个select下拉框,用于修改记录状态(Odesláno、Přijato、Odmítnuto、Předáno BKOM),修改后同步更新数据库状态。目前所有记录下拉框功能正常,唯独第一条记录修改状态后无任何反应,表单共加载5行数据,仅首条出现该问题。
表单渲染代码
<?php if (mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_assoc($result)) { $stav = htmlspecialchars($row['stav']); echo "<tr data-stav='$stav'>"; echo "<td><input type='checkbox' name='selected_ids[]' value='" . $row['id'] . "'></td>"; echo "<td>" . $row['id'] . "</td>"; echo "<td>" . $stav . "</td>"; echo "<td>" . $row['datum_vlozeni'] . "</td>"; echo "<td>" . $row['pocet_stojanu'] . "</td>"; echo '<td> <form method="post" action="php/change_stav.php">'; echo '<input type="hidden" name="id" value="' . $row['id'] . '">'; echo '<select name="stav" onchange="this.form.submit()">'; echo '<option value="odesláno" ' . ($stav === 'odesláno' ? 'selected' : '') . '>Odesláno</option>'; echo '<option value="přijato" ' . ($stav === 'přijato' ? 'selected' : '') . '>Přijato</option>'; echo '<option value="odmítnuto" ' . ($stav === 'odmítnuto' ? 'selected' : '') . '>Odmítnuto</option>'; echo '<option value="Předáno BKOM" ' . ($stav === 'Předáno BKOM' ? 'selected' : '') . '>Předáno BKOM</option>'; echo '</select>'; echo '</form>'; echo '</td>'; echo '<td> <a href="update.php?hash_kod=' . $row['hash_kod'] . '" title="Upravit"> <i class="bi bi-pencil-square"></i> </a> <a href="php/export_pdf.php?hash_kod='. $row['hash_kod'] .'" target="_blank" title="Export do PDF"> <i class="bi bi-file-earmark-pdf"></i> </a> </td>'; echo "</tr>"; } } else { echo "<tr><td colspan='6'>Žádné záznamy k zobrazení.</td></tr>"; } ?>
状态更新处理代码
<?php if ($_SERVER["REQUEST_METHOD"] === "POST") { $servername = "localhost"; $username = "root"; $password = ""; $dbname = "podnety"; $conn = new mysqli($servername, $username, $password, $dbname); $conn->set_charset("utf8"); $id = mysqli_real_escape_string($conn, $_POST['id']); $stav = mysqli_real_escape_string($conn, $_POST['stav']); $sql = "UPDATE podnety SET stav = '$stav' WHERE id = '$id' AND delete_record IS NULL"; if (mysqli_query($conn, $sql)) { header("Location: ../admin.php"); exit; } else { echo "Chyba: " . mysqli_error($conn); } } ?>
问题排查与解决
1. 检查表单嵌套冲突
查看页面整体结构,是否存在外层表单包裹整个表格?如果是,首条记录的内部表单会被外层表单嵌套,导致this.form.submit()提交的是外层表单而非当前行的小表单,无法传递正确的id和stav参数。
- 解决办法:移除外层包裹表格的表单,确保每个下拉框的小表单都是独立的顶级表单;或分离外层表单与下拉框的提交逻辑。
2. 验证首条记录的HTML渲染
右键页面→查看源码,对比首条与其他记录的表单HTML结构,检查:
hidden字段的id值是否正确输出;select的onchange事件是否完整;- 是否存在未闭合的HTML标签破坏表单结构。
若发现标签拼接错误,修正PHP代码中的引号匹配或字符串拼接逻辑。
3. 排查数据库条件限制
检查首条记录的delete_record字段值,更新SQL包含AND delete_record IS NULL条件,若该字段不为NULL,更新语句不会修改任何行。
- 验证方式:直接在数据库执行
UPDATE podnety SET stav = 'přijato' WHERE id = [首条记录ID],若生效则需调整delete_record条件或修正该字段值。
优化建议:改用PDO预处理防注入
替换原MySQLi代码为PDO预处理语句,提升安全性:
<?php if ($_SERVER["REQUEST_METHOD"] === "POST") { $dsn = "mysql:host=localhost;dbname=podnety;charset=utf8"; $username = "root"; $password = ""; try { $pdo = new PDO($dsn, $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "UPDATE podnety SET stav = :stav WHERE id = :id AND delete_record IS NULL"; $stmt = $pdo->prepare($sql); $stmt->bindParam(':stav', $_POST['stav']); $stmt->bindParam(':id', $_POST['id']); $stmt->execute(); header("Location: ../admin.php"); exit; } catch(PDOException $e) { echo "Chyba: " . $e->getMessage(); } } ?>
内容的提问来源于stack exchange,提问作者Jiří Komínek
相关产品推荐
相关产品推荐

