
本文详解如何在 php 中实现 csv 文件批量导入 mysql 的同时,为每一行数据动态生成唯一 id 和对应 qr 码图片,并安全写入数据库。
本文详解如何在 php 中实现 csv 文件批量导入 mysql 的同时,为每一行数据动态生成唯一 id 和对应 qr 码图片,并安全写入数据库。
在批量数据导入场景中,仅插入原始字段远远不够——常需为每条记录绑定唯一标识(如工号、设备码)并配套生成可扫描的 QR 码。上文示例的核心问题在于:QR 码生成逻辑被错误地置于循环外部,导致所有记录共用同一个 uniqid(),违背“每行独立编码”的业务需求。
以下是经过优化、安全、可直接部署的完整解决方案:
✅ 正确逻辑结构
- 每次读取 CSV 一行(fgetcsv)后,立即生成专属唯一 ID;
- 基于该 ID 调用 QRcode::png() 生成 PNG 图片并保存至指定路径;
- 将 ID 与 CSV 中的字段(如姓名)一同插入数据库;
- 全程在循环内完成,确保“一行一码一记录”。
✅ 安全增强版代码(含防 SQL 注入与基础异常处理)
<?php
$conn = getdb();
if (isset($_POST["Import"]) && isset($_FILES["file"])) {
$filename = $_FILES["file"]["tmp_name"];
// 验证上传文件
if ($_FILES["file"]["error"] !== UPLOAD_ERR_OK) {
echo "<script>alert('文件上传失败,请重试'); window.location='ad-bulk.php';</script>";
exit;
}
if ($_FILES["file"]["size"] <= 0) {
echo "<script>alert('CSV 文件为空'); window.location='ad-bulk.php';</script>";
exit;
}
$file = fopen($filename, "r");
if (!$file) {
echo "<script>alert('无法打开 CSV 文件'); window.location='ad-bulk.php';</script>";
exit;
}
// 确保临时目录存在且可写
$path = '../temp/';
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
$successCount = 0;
$errorCount = 0;
while (($row = fgetcsv($file, 10000, ",")) !== FALSE) {
if (empty($row[0])) continue; // 跳过空姓名行
// ✅ 每行生成独立唯一码
$uniqueId = uniqid('IT-', true); // 加 true 提高唯一性(基于微秒+熵)
$text = $uniqueId;
$fileName = $path . $uniqueId . ".png";
$ecc = 'L';
$pixelSize = 20;
$frameSize = 1;
try {
// 生成 QR 码(需已引入 phpqrcode 库)
QRcode::png($text, $fileName, $ecc, $pixelSize, $frameSize);
// ✅ 使用预处理语句防止 SQL 注入(强烈推荐)
$stmt = $conn->prepare("INSERT INTO users (code, name) VALUES (?, ?)");
$stmt->bind_param("ss", $uniqueId, $row[0]);
if ($stmt->execute()) {
$successCount++;
} else {
$errorCount++;
error_log("SQL Error: " . $stmt->error . " for data: " . $row[0]);
}
$stmt->close();
} catch (Exception $e) {
$errorCount++;
error_log("QR Generation Failed: " . $e->getMessage());
}
}
fclose($file);
// 统一反馈结果
if ($errorCount === 0) {
echo "<script>
alert('成功导入 {$successCount} 条记录,QR 码已生成');
window.location = 'ad-bulk.php';
</script>";
} else {
echo "<script>
alert('部分导入失败:成功 {$successCount} 条,失败 {$errorCount} 条,请检查日志');
window.location = 'ad-bulk.php';
</script>";
}
}
?>⚠️ 关键注意事项
- 依赖安装:确保已正确引入 PHP QR Code 库(如通过 require_once 'phpqrcode/qrlib.php';);
- 目录权限:../temp/ 目录需具备 Web 服务器写入权限(Linux 下常用 chmod 755 temp);
- 数据库字段适配:确认 users 表中 code 字段类型为 VARCHAR(32) 或更长(uniqid() 默认约 13 字符,加前缀后建议 ≥24);
- 性能提示:单次导入不宜超过 1000 行;超量建议启用事务 + 分批提交(mysqli_begin_transaction() + commit());
- 安全性升级:生产环境务必禁用 mysqli_query() 拼接 SQL,坚持使用预处理语句(如上例所示)。
✅ 总结
将 QR 码生成嵌入 CSV 解析循环内部,是实现“每行一码”的技术关键;配合预处理语句、目录校验与结构化错误统计,即可构建健壮、可维护的批量导入流程。此方案不仅解决当前需求,也为后续扩展(如记录导入时间、操作员、文件名溯源等)预留了清晰接口。










