PHP导入JSON至MySQL仅插入首条记录问题求助
问题分析与解决方法
你的问题出在SQL语句执行方式和代码逻辑上,咱们一步步拆解:
为什么只插入第一条记录?
- mysqli_query()不支持多语句执行:你在循环里不断把INSERT语句追加到
$query变量,然后每次循环都用mysqli_query()执行整个$query。但mysqli_query()默认只能执行单条SQL语句,当$query包含多条用分号分隔的SQL时,它只会执行第一条,后续的所有语句都会被直接忽略。 - 重复执行已插入的语句:第一次循环执行后,第一条记录已经插入;第二次循环时
$query变成了「第一条INSERT + 第二条INSERT」,这时候执行mysqli_query()只会再次尝试插入第一条记录(如果没有唯一键约束,会生成重复数据,但你看不到后续记录的原因是第二条根本没被执行)。 - 潜在的SQL注入与语法错误:直接把JSON里的值拼到SQL字符串中,如果某个字段包含单引号(比如
sale_item是O'Neil),会直接导致SQL语法错误,整个插入流程中断。
修复方案(两种可选)
方案1:单条循环插入(安全易维护,适合少量记录)
使用预处理语句执行单条INSERT,既避免SQL注入,也保证每条记录都能正确插入:
<?php $connect = mysqli_connect("localhost", "root", "", "mytest"); // 先检查数据库连接是否成功 if (mysqli_connect_errno()) { die("数据库连接失败: " . mysqli_connect_error()); } $filename = "path.json"; $data = file_get_contents($filename); $array = json_decode($data, true); // 初始化预处理语句,绑定参数占位符 $stmt = mysqli_prepare($connect, "INSERT INTO tbl_sales(sale_item, sale_qty, local_row_added_on, last_edited_on) VALUES (?, ?, ?, ?)"); // 绑定参数类型:s=字符串,i=整数,s=字符串,s=字符串 mysqli_stmt_bind_param($stmt, "siss", $sale_item, $sale_qty, $local_row_added_on, $last_edited_on); foreach($array as $row) { // 从JSON数组中取出对应值 $sale_item = $row["sale_item"]; $sale_qty = $row["sale_qty"]; $local_row_added_on = $row["local_row_added_on"]; $last_edited_on = $row["last_edited_on"]; // 执行当前记录的插入 mysqli_stmt_execute($stmt); } // 清理资源 mysqli_stmt_close($stmt); mysqli_close($connect); echo "<h1>Successfully Imported JSON Data</h1>"; ?>
方案2:单条多值INSERT(效率更高,适合大量记录)
把所有记录的值拼接成一条INSERT语句,一次性执行,减少数据库交互次数:
<?php $connect = mysqli_connect("localhost", "root", "", "mytest"); if (mysqli_connect_errno()) { die("数据库连接失败: " . mysqli_connect_error()); } $filename = "path.json"; $data = file_get_contents($filename); $array = json_decode($data, true); $values = []; foreach($array as $row) { // 对每个字段进行转义,防止SQL注入和语法错误 $sale_item = mysqli_real_escape_string($connect, $row["sale_item"]); $sale_qty = mysqli_real_escape_string($connect, $row["sale_qty"]); $local_row_added_on = mysqli_real_escape_string($connect, $row["local_row_added_on"]); $last_edited_on = mysqli_real_escape_string($connect, $row["last_edited_on"]); // 把当前记录的格式化为值组 $values[] = "('$sale_item', '$sale_qty', '$local_row_added_on', '$last_edited_on')"; } // 拼接成完整的INSERT语句 $query = "INSERT INTO tbl_sales(sale_item, sale_qty, local_row_added_on, last_edited_on) VALUES " . implode(", ", $values); // 执行并判断结果 if(mysqli_query($connect, $query)) { echo "<h1>Successfully Imported JSON Data</h1>"; } else { echo "插入失败: " . mysqli_error($connect); } mysqli_close($connect); ?>
额外提醒
- 你不需要插入JSON中的
id字段,因为表中id是自增主键,数据库会自动生成唯一值; - 建议始终使用预处理语句或者字段转义来防止SQL注入,这是后端开发的基础安全规范;
- 如果插入大量记录,方案2的效率会远高于方案1,因为减少了多次数据库往返的开销。
内容的提问来源于stack exchange,提问作者S.Sakthybaalan
相关产品推荐
相关产品推荐

