PHP中如何同时执行多查询并填充表单字段?
解决PHP同时查询并插入数据的问题
你的问题出在原代码中覆盖了查询变量,并且没有正确处理多查询的结果集。另外,你的代码存在严重的SQL注入风险,这是必须先修复的问题,我会一步步帮你解决:
问题分析
- 原代码里你先定义了
$query = "SELECT ...",紧接着又把$query赋值为INSERT语句,导致实际上只执行了INSERT操作。而INSERT语句执行成功后返回的是布尔值true,不是查询结果集,所以调用mysqli_num_rows($result)时自然会报错——它需要的是mysqli_result类型的对象。 - 直接将用户输入的
$user_id拼接到SQL语句中,非常容易被SQL注入攻击,必须使用预处理语句来规避这个安全隐患。
修复后的完整代码
我用预处理语句重写了代码,先执行SELECT获取数据填充表单,再执行INSERT将数据写入scan表,逻辑清晰且安全:
<?php // 初始化表单变量 $osha = ""; $firstname = ""; $lastname = ""; $company = ""; $trade = ""; if(isset($_POST['search'])) { // 获取用户输入 $user_id = $_POST['user_id']; // 连接数据库并检查连接状态 $connect = mysqli_connect("127.0.0.1", "root", "root","demodb"); if (!$connect) { die("数据库连接失败: " . mysqli_connect_error()); } // 第一步:执行SELECT查询获取用户数据(预处理防SQL注入) $select_query = "SELECT * FROM Users WHERE user_id = ? LIMIT 1"; $stmt = mysqli_prepare($connect, $select_query); mysqli_stmt_bind_param($stmt, "i", $user_id); // "i"表示参数为整数类型 mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if(mysqli_num_rows($result) > 0) { // 获取数据填充表单变量 $row = mysqli_fetch_array($result); $osha = $row['osha']; $firstname = $row['firstname']; $lastname = $row['lastname']; $company = $row['company']; $trade = $row['trade']; // 第二步:执行INSERT语句将数据插入scan表(同样用预处理) $insert_query = "INSERT INTO scan (user_id, osha, firstname, lastname, company, trade, email, picture) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; $stmt_insert = mysqli_prepare($connect, $insert_query); mysqli_stmt_bind_param($stmt_insert, "iissssss", $row['user_id'], $row['osha'], $row['firstname'], $row['lastname'], $row['company'], $row['trade'], $row['email'], $row['picture'] ); mysqli_stmt_execute($stmt_insert); // 检查插入是否成功 if(mysqli_stmt_affected_rows($stmt_insert) > 0) { echo "<p style='color:green;'>数据已成功插入scan表</p>"; } else { echo "<p style='color:red;'>插入scan表失败: " . mysqli_error($connect) . "</p>"; } mysqli_stmt_close($stmt_insert); } else { echo "<p style='color:red;'>未找到该ID的用户</p>"; // 清空表单变量 $osha = ""; $firstname = ""; $lastname = ""; $company = ""; $trade = ""; } // 清理资源 mysqli_stmt_close($stmt); mysqli_free_result($result); mysqli_close($connect); } ?> <!DOCTYPE html> <html> <head> <title> PHP FIND DATA </title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <form action="barcode.php" method="post"> Id:<input type="text" name="user_id"><br><br> Osha #:<input type="text" name="osha" value="<?php echo htmlspecialchars($osha);?>"><br><br> First Name:<input type="text" name="firstname" value="<?php echo htmlspecialchars($firstname);?>"><br><br> Last Name:<input type="text" name="lastname" value="<?php echo htmlspecialchars($lastname);?>"><br><br> Company:<input type="text" name="company" value="<?php echo htmlspecialchars($company);?>"><br><br> Trade:<input type="text" name="trade" value="<?php echo htmlspecialchars($trade);?>"><br><br> <input type="submit" name="search" value="Find"> </form> </body> </html>
关键改进点
- SQL注入防护:使用
mysqli_prepare预处理语句和mysqli_stmt_bind_param绑定参数,彻底避免直接拼接用户输入带来的安全风险。 - 分步骤执行逻辑:先执行SELECT获取数据填充表单,再执行INSERT操作,流程清晰,便于调试和维护。
- 错误处理增强:增加了数据库连接失败的判断,以及插入操作的结果检查,方便快速排查问题。
- XSS防护:用
htmlspecialchars()处理输出到表单的值,防止跨站脚本攻击。
关于mysqli_multi_query的补充说明
如果你坚持想用mysqli_multi_query,需要注意它的结果集处理逻辑:执行后要先用mysqli_store_result()获取第一个查询的结果,再用mysqli_next_result()处理后续查询。但这种方式不如分开执行预处理语句清晰,且同样要注意SQL注入问题,所以更推荐上面的预处理方案。
内容的提问来源于stack exchange,提问作者Unxcellent
相关产品推荐
相关产品推荐

