如何用PHP将数据导入MySQL多表?现有代码需扩展至product_details表
问题:PHP导入MySQL数据至多表的脚本验证与优化
初始脚本(仅导入products表)
foreach ($file_data as $row) { $sku = $row[$_POST["sku"]]; $title = $row[$_POST["title"]]; $slug = $row[$_POST["title"]]; $product_type = "physical"; $description = $row[$_POST["description"]]; } if(isset($sku)) { $query = " INSERT INTO products (sku, slug, product_type) VALUES ".implode(",", $sku).",".implode(",", $slug).",".implode(",", $product_type)." "; $statement = $connect->prepare($query); if($statement->execute()) { echo 'Data Imported Successfully'; } }
当前脚本仅能将数据导入products表,需求是将$title和$description导入第二个表product_details。
更新后的脚本
foreach ($file_data as $row) { $sku = $row[$_POST["sku"]]; $title = $row[$_POST["title"]]; $slug = $row[$_POST["slug"]]; $product_type = "physical"; $description = $row[$_POST["description"]]; if (isset($sku)) { $statement = $connect->prepare("INSERT INTO products (sku, slug, product_type) VALUES '$sku','$slug','$product_type'"); $statement2 = $connect->prepare("INSERT INTO product_details (title, description) VALUES '$title','$description'"); if (!$statement->execute()) { $error = 'None or part of the data was updated'; } } } echo $error ?? 'Data Updated Successfully';
请确认该更新后的脚本是否正确,或提供更优的实现方案。
脚本问题分析
- SQL注入风险:直接将变量拼接进SQL语句,未使用参数绑定,存在严重安全漏洞。
- 数据关联缺失:
product_details表未与products表通过关联字段(如product_id)绑定,两条数据会孤立,无法对应关联。 - 错误处理不完善:仅判断
products表的插入结果,未处理product_details的插入错误,且循环内未重置错误状态,易导致错误信息覆盖。 - 执行效率低:每次循环重复预编译SQL语句,增加数据库开销。
优化后的实现方案
// 提前预编译SQL,避免循环内重复编译 $stmtProducts = $connect->prepare("INSERT INTO products (sku, slug, product_type) VALUES (?, ?, ?)"); $stmtDetails = $connect->prepare("INSERT INTO product_details (product_id, title, description) VALUES (?, ?, ?)"); // 绑定参数占位符 $stmtProducts->bind_param("sss", $sku, $slug, $product_type); $stmtDetails->bind_param("iss", $productId, $title, $description); $error = null; $product_type = "physical"; foreach ($file_data as $row) { $sku = $row[$_POST["sku"]] ?? null; $title = $row[$_POST["title"]] ?? null; $slug = $row[$_POST["slug"]] ?? null; $description = $row[$_POST["description"]] ?? null; if (empty($sku)) { continue; // SKU为空则跳过当前行 } // 开启事务,保证两张表数据一致性 $connect->begin_transaction(); try { // 插入products表 $stmtProducts->execute(); // 获取刚插入的产品自增ID $productId = $connect->insert_id; // 插入product_details表,关联product_id $stmtDetails->execute(); // 提交事务 $connect->commit(); } catch (Exception $e) { // 回滚事务,避免部分数据插入 $connect->rollback(); $error = "导入行数据失败: " . $e->getMessage(); // 可选:若要终止后续导入,取消下面注释 // break; } } echo $error ?? "数据导入成功"; // 关闭预编译语句 $stmtProducts->close(); $stmtDetails->close();
关键改进点
- 参数绑定:用
bind_param避免SQL注入,同时提升SQL执行效率。 - 事务处理:确保两张表的插入操作要么全部成功,要么全部回滚,保证数据一致性。
- 关联键处理:通过
insert_id获取products表的自增ID,作为product_details的关联字段,解决数据孤立问题。 - 空值容错:用
??运算符处理可能的空值,避免Undefined offset错误。 - 预编译复用:将预编译语句放在循环外,减少数据库编译开销。
内容的提问来源于stack exchange,提问作者Marcin Wierzycki
相关产品推荐
相关产品推荐

