首页 > 解决方案 > 如何在使用 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 ......

标签: phpmysqlsql

解决方案


为什么不简单地使用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上面的链接文档中描述了更多有用的选项。


推荐阅读