php - 如何在使用 PHP 导入 SQL 之前正确转义 CSV 文件
问题描述
我必须建立报告网站,其中将使用从另一个系统导出的 csv 文件导入 SQL 数据。
我构建了代码,但我无法继续它,要导入 SQL,我只有消息QUERY FAILED,而不是来自 SQL 的错误或与数据库的连接。
有人可以查看我的代码并写信告诉我我的错误在哪里吗?我用户对数据进行了转义,因为我收到了类似...的数据"John's company"
:
<?php
if(isset($_POST['import'])) {
$filename = $_FILES['file']['tmp_name'];
if($_FILES['file']['size'] > 0 ) {
$file = fopen($filename, 'r');
while (($data = fgetcsv($file, 10000, ",")) !== FALSE ) {
$data = array_map('mysqli_real_escape_string', $data);
$query = "INSERT INTO purchasing ";
$query .= "(
purchase_req,
pr_date,
pr_item,
pr_created_by,
po_created_by,
purch_group,
purchase_ord,
po_date,
po_item,
po_state,
vendor_numb,
vendor_name,
mat_desc,
gl_acc,
cost_cent,
po_qty,
po_del_date,
po_delivered_qty,
po_to_be_del
) ";
$query .= "VALUES (
'" . $data[0] . "',
'" . $data[1] . "',
'" . $data[2] . "',
'" . $data[3] . "',
'" . $data[4] . "',
'" . $data[5] . "',
'" . $data[6] . "',
'" . $data[7] . "',
'" . $data[8] . "',
'" . $data[9] . "',
'" . $data[10] . "',
'" . $data[11] . "',
'" . $data[12] . "',
'" . $data[13] . "',
'" . $data[14] . "',
'" . $data[15] . "',
'" . $data[16] . "',
'" . $data[17] . "',
'" . $data[18] . "'
) ";
$send_to_database = mysqli_query($conn, $query);
if(!$send_to_database) {
die("QUERY FAILED <br>" . mysqli_error($conn));
} else {
header("Location: index.php");
}
}
fclose($file);
}
}
?>
/// 建议后更新的代码
<?php
if(isset($_POST['import'])) {
$filename = $_FILES['file']['tmp_name'];
if($_FILES['file']['size'] > 0 ) {
$file = fopen($filename, 'r');
$conn = new mysqli("localhost", "####", "####", "####");
if($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$stmt = $mysqli->prepare("INSERT INTO purchasing (purchase_req, pr_date, pr_item, pr_created_by, po_created_by, purch_group, purchase_ord, po_date, po_item, po_state, vendor_numb, vendor_name, mat_desc, gl_acc, cost_cent, po_qty, po_del_date, po_delivered_qty, po_to_be_del) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ");
fgetcsv($file, 10000, ",");
while(($data = fgetcsv($file, 10000, ",")) !== FALSE) {
$data = fgetcsv($file);
$stmt->bind_param("sssssssssssssssssss", $data[0], $data[1], $data[2], $data[3], $data[4], $data[5], $data[6], $data[7], $data[8], $data[9], $data[10], $data[11], $data[12], $data[13], $data[14], $data[15], $data[16], $data[17], $data[18]);
$stmt->execute();
}
fclose($file);
}
}
?>
对于第二种情况,我打印了数组,但我又不能将它发送到 SQL ......
解决方案
为什么不简单地使用MySQLLOAD DATA INFILE
语法通过单个 SQL 查询一次加载文件?
这个 MySQL 插件是加载 CSV 文件的有效方法,同时防止 SQL 注入和处理引用问题。它还避免了使用 php.ini 打开和循环文件。根据MySQL 文档:
从文本文件加载表格时,使用
LOAD DATA
. 这通常比使用INSERT
语句快 20 倍。
这应该很简单:
LOAD DATA INFILE '$filename'
INTO TABLE purchasing(
purchase_req,
pr_date, pr_item,
pr_created_by,
po_created_by,
purch_group,
purchase_ord,
po_date,
po_item,
po_state,
vendor_numb,
vendor_name,
mat_desc,
gl_acc,
cost_cent,
po_qty,
po_del_date,
po_delivered_qty,
po_to_be_del
)
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\r\n' -- or maybe '\n'?
;
注意:该OPTIONALLY ENCLOSED BY '"'
选项应该处理像"John's company"
. LOAD DATA INFILE
上面的链接文档中描述了更多有用的选项。
推荐阅读
- java - 有没有办法使用 MapStruct 将空字符串映射到 null?
- node.js - 是否可以在 twilio 中从多个呼叫中添加一个人?
- javascript - 如果函数 javascript 不起作用,则只有 backgroundColor 样式
- apache - 为什么在收到 301 状态响应时将“主机”标头设置为不正确的值
- postgresql - 磁盘位图索引上发生了什么?
- reactjs - Conditionally applying className to a react component depending on where the component is used
- node.js - 离线先react原生应用(nodejs、mongodb)
- powershell - 在变量 remove-item 中找到的 Foreach 路径
- google-analytics - 数据洞察 - 一条图表线中的 GA 事件很少
- wso2 - 将第一个 prosy 服务的输出传递给 WSO2 集成工作室中的第二个代理服务