PHP:文本框输入与数据库表校验失效问题排查
问题分析:表单校验失效直接执行插入的原因及修复方案
我帮你排查了代码里的问题,校验环节失效主要是几个关键错误导致的,咱们一步步拆解:
核心问题1:重复调用mysqli_query且参数错误
你这段代码里的校验逻辑有个致命错误:
$query = mysqli_query($dbh, "SELECT serials FROM `wp27_test6serial` WHERE `serials` = '$line'"); $result = mysqli_query($dbh, $query); // 这里完全错了!
mysqli_query的第二个参数必须是SQL语句字符串,但你把第一次查询返回的结果集对象传进去了,这会导致$result直接变成false。后续mysqli_num_rows($result)判断时,传入false会返回0,相当于永远判定“条目不存在”,自然就跳过校验直接执行插入了。
核心问题2:字段名不一致
查询时用的是serials字段,但插入时写的是rtxserials:
// 查询字段是serials $query = mysqli_query($dbh, "SELECT serials FROM `wp27_test6serial` WHERE `serials` = '$line'"); // 插入字段是rtxserials $query = mysqli_query($dbh, "INSERT INTO wp27_test6serial (rtxserials) VALUES ('$line')");
就算校验逻辑正常,也会出现“查询的字段和插入的字段不是同一个”的问题,等于白校验。
额外问题:SQL注入风险+逻辑不严谨
- 直接把用户输入的
$line拼进SQL语句,没有任何转义处理,很容易被攻击者篡改数据库。 - 当前代码如果前几条插入成功,后面遇到重复条目直接
die,会导致部分数据已经插入数据库,不符合“要么全成功要么全失败”的预期。
修复后的完整代码
我把这些问题都修正了,还加了事务处理确保数据一致性:
<?php // 注意:表单提交一般用POST,所以这里用$_POST判断提交状态 if (isset($_POST["submit"])) { $host = "localhost"; $user = "root"; $password = "password"; $database = "test"; // 建立数据库连接 $dbh = mysqli_connect($host, $user, $password, $database); if (mysqli_connect_errno()) { die('Unable to connect to database ' . mysqli_connect_error()); } // 开启事务:确保所有条目要么全插入,要么全不插入 mysqli_begin_transaction($dbh); try { $text = trim($_POST['serial']); $textAr = explode("\n", $text); $textAr = array_filter($textAr, 'trim'); // 去除空行和多余的\r字符 foreach ($textAr as $line) { // 转义用户输入,彻底避免SQL注入 $escaped_line = mysqli_real_escape_string($dbh, $line); // 直接执行查询并获取结果集 $check_result = mysqli_query($dbh, "SELECT serials FROM `wp27_test6serial` WHERE `serials` = '$escaped_line'"); if (!$check_result) { throw new Exception(mysqli_error($dbh)); } // 校验条目是否存在 if (mysqli_num_rows($check_result) > 0) { throw new Exception("Entry already exists: {$line}"); } // 插入数据(注意字段名和查询时统一) $insert_result = mysqli_query($dbh, "INSERT INTO wp27_test6serial (serials) VALUES ('$escaped_line')"); if (!$insert_result) { throw new Exception(mysqli_error($dbh)); } } // 所有操作都成功,提交事务 mysqli_commit($dbh); echo 'All serials submitted successfully!'; } catch (Exception $e) { // 出错时回滚所有操作,避免部分数据插入 mysqli_rollback($dbh); die('Error: ' . $e->getMessage()); } // 关闭数据库连接 mysqli_close($dbh); } ?>
关键修复点说明
- 修正校验逻辑:去掉重复的
mysqli_query调用,直接用第一次查询的结果集做存在性判断。 - 统一字段名:确保查询和插入的字段名一致(你可以根据实际表结构调整)。
- 防SQL注入:用
mysqli_real_escape_string转义用户输入的内容。 - 事务处理:用
mysqli_begin_transaction、mysqli_commit、mysqli_rollback保证数据的原子性。 - 错误捕获:用
try-catch捕获所有异常,给出明确的错误提示。
内容的提问来源于stack exchange,提问作者Dian Mangalapallil
相关产品推荐
相关产品推荐

