简体   繁体   English

使用 PHP 将 CSV 文件上传到 SQL 服务器时出现问题

[英]Problems with uploading CSV file to SQL Server with PHP

I have created a web application to allow users to upload CSV files into SQL Server.我创建了一个 web 应用程序,以允许用户将CSV文件上传到 SQL 服务器。 I have 8 columns in total.我总共有 8 列。 The id column in SQL Server is auto-increment so minus that column. SQL 服务器中的 id 列是自动递增的,因此减去该列。 The upload was successful however data imported are all null in each column.上传成功,但是每列导入的数据都是null Also the number of records in my CSV is less than 100 however my SQL Server is showing more than 100 records imported which doesn't tally.此外,我的CSV中的记录数少于 100 条,但我的 SQL 服务器显示导入的记录超过 100 条,这些记录不相符。 Can anyone help to check what is wrong with my code?任何人都可以帮助检查我的代码有什么问题吗?

Below is my code and a screenshot of my CSV file and SQL Server table.下面是我的代码和我的 CSV 文件和 SQL 服务器表的屏幕截图。

<?php

$self = $_SERVER['PHP_SELF'];
$request = $_SERVER['REQUEST_METHOD'];

if (!isset($_GET['success'])) {
$get_success = "";
}
else {
$get_success = $_GET['success'];
}

if (!empty($_FILES)) { 

    /* Format the errors and die */
    
    function get_last_error() {
        $retErrors = sqlsrv_errors(SQLSRV_ERR_ALL);
        $errorMessage = 'No errors found';

        if ($retErrors != null) {
            $errorMessage = '';

            foreach ($retErrors as $arrError) {
                $errorMessage .= "SQLState: ".$arrError['SQLSTATE']."<br>\n";
                $errorMessage .= "Error Code: ".$arrError['code']."<br>\n";
                $errorMessage .= "Message: ".$arrError['message']."<br>\n";
            }
        }

        die ($errorMessage);
    }

    /* connect */
    function connect() {
        if (!function_exists('sqlsrv_num_rows')) { // Insure sqlsrv_1.1 is loaded.
            die ('sqlsrv_1.1 is not available');
        }

        /* Log all Errors */
        sqlsrv_configure("WarningsReturnAsErrors", TRUE);        // BE SURE TO NOT ERROR ON A WARNING
        sqlsrv_configure("LogSubsystems", SQLSRV_LOG_SYSTEM_ALL);
        sqlsrv_configure("LogSeverity", SQLSRV_LOG_SEVERITY_ALL);

        $conn = sqlsrv_connect('servername', array
        (
        'UID' => '',
        'PWD' => '',
        'Database' => 'databasename',
        'CharacterSet' => 'UTF-8',
        'MultipleActiveResultSets' => true,
        'ConnectionPooling' => true,
        'ReturnDatesAsStrings' => true,
        ));

        if ($conn === FALSE) {
            get_last_error();
        }

        return $conn;
    }

    function query($conn, $query) {
        $result = sqlsrv_query($conn, $query);
        if ($result === FALSE) {
            get_last_error();
        }
        return $result;
    }

    /* Prepare a reusable query (prepare/execute) */
    
    function prepare ( $conn, $query, $params ) {
        $result = sqlsrv_prepare($conn, $query, $params);
        if ($result === FALSE) {
            get_last_error();
        }
        return $result;
    }

    /*
    do the deed. once prepared, execute can be called multiple times
    getting different values from the variable references.
    */
    
    function execute ( $stmt ) {
        $result = sqlsrv_execute($stmt);
        if ($result === FALSE) {
            get_last_error();
        }
        return $result;
    }

    function fetch_array($query) {
        $result = sqlsrv_fetch_array($query, SQLSRV_FETCH_ASSOC);
        if ($result === FALSE) {
            get_last_error();
        }
        return $result;
    }

    $conn = connect();

    /* prepare the statement */
    $query = "INSERT TABLEName values ( ? , ? , ? , ?, ?, ?, ?, ?)";
    $param1 = null; // this will hold col1 from the CSV
    $param2 = null; // this will hold col2 from the CSV
    $param3 = null; // this will hold col3 from the CSV
    $param4 = null; // this will hold col4 from the CSV
    $param5 = null; // this will hold col5 from the CSV
    $param6 = null; // this will hold col6 from the CSV
    $param7 = null; // this will hold col7 from the CSV
    $param8 = null; // this will hold col8 from the CSV
    $params = array( $param1, $param2, $param3, $param4, $param5, $param6, $param7, $param8 );
    $prep = prepare ( $conn, $query, $params );
    //$result = execute ( $prep );

    //get the csv file 
    
    $file = $_FILES["csv"]["tmp_name"]; 
    
  /*
    Here is where you read in and parse your CSV file into an array.
    That may get too large, so you would have to read smaller chunks of rows.
  */
  
    $csv_array = file($file);
    foreach ($csv_array as $row_num => $row) {
        $row = trim ($row);
        $column = explode ( ',' , $row );
        $param1 = $column[0];
        $param2 = $column[1];
        $param3 = $column[2];
        $param4 = $column[3];
        $param5 = $column[4];
        $param6 = $column[5];
        $param7 = $column[6];
        $param8 = $column[7];
        // insert the row
        
        $result = execute ( $prep );
    }
    
/* Free statement and connection resources. */

sqlsrv_close($conn);
header( "Location: uploadcsv.php?success=1" );
}

?>


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>CSV Upload</title>
</head>
<body>
<?php if (!empty($get_success)) { echo "<b>Your file has been imported.</b><br><br>"; } //generic success notice ?> 

<form action="" method="post" enctype="multipart/form-data" name="uploadcsv" id="uploadcsv"> 
  Upload a CSV file from your computer: <br /> 
  <input name="csv" type="file" id="csv" /> 
  <input type="submit" name="Submit" value="Submit" /> 
</form> 


<body>
</html>

CSV data file CSV数据文件

CSV

sqlserver table sqlserver 表

在此处输入图像描述

There are two major problems with the code posted:贴出的代码有两个主要问题:

  1. CSV data is not being read in correctly, and CSV 数据未正确读取,并且
  2. The $params array supplied to prepare() isn't being updated correctly.提供给prepare()$params数组未正确更新。

Problem 1: Reading in CSV.问题 1:读取 CSV。

You're using PHP's file() method to read CSV files.您正在使用 PHP 的file()方法来读取 CSV 文件。

If you're trying to parse CSV files line-by-line and then split lines on commas you're doing it wrong.如果您尝试逐行解析 CSV 文件,然后用逗号分隔行,那么您做错了。 Have a read through RFC 4180 Common Format and MIME Type for Comma-Separated Values (CSV) Files to see how CSV files are structured and notice that field datas can contain commas, quotes and line break characters.阅读RFC 4180 Common Format and MIME Type for Comma-Separated Values (CSV) Files ,了解 CSV 文件的结构,并注意字段数据可以包含逗号、引号和换行符。 ie: You need a character-oriented state machine to parse them.即:您需要一个面向字符的 state 机器来解析它们。

The correct way to do it is to use a CSV parsing function or library that somebody else has already written and debugged for you, eg: fgestcsv() .正确的方法是使用 CSV 解析 function 或其他人已经为您编写和调试的库,例如: fgestcsv()

Consider the following example...考虑以下示例...

foo1.csv: foo1.csv:

col1,col2,col3
alpha,bravo,charlie
"hello,
""cruel""
world!",bravo,charlie

foo1.php: foo1.php:

<?php
if (($handle = fopen("foo1.csv", "r")) !== FALSE) {
    $row = 1;
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        print "Row $row: ";
        var_dump($data);
        $row++;
    }
    fclose($handle);
}
?>

When run this outputs...运行此输出时...

% php -f foo1.php
Row 1: array(3) {
  [0]=>
  string(4) "col1"
  [1]=>
  string(4) "col2"
  [2]=>
  string(4) "col3"
}
Row 2: array(3) {
  [0]=>
  string(5) "alpha"
  [1]=>
  string(5) "bravo"
  [2]=>
  string(7) "charlie"
}
Row 3: array(3) {
  [0]=>
  string(19) "hello,
"cruel"
world!"
  [1]=>
  string(5) "bravo"
  [2]=>
  string(7) "charlie"
}

Problem 2: Updating $params correctly问题 2:正确更新 $params

The code posted constructs an array from variables and then updates the variables with CSV data.发布的代码从变量构造一个数组,然后使用 CSV 数据更新变量。 This won't work, consider the following...这不起作用,请考虑以下...

foo2.php: foo2.php:

<?php
$param1 = null;
print "\$param1 = ";
var_dump($param1);

$params = array($param1);
print "\$params = ";
var_dump($params);

$param1 = 42;
print "\$param1 = ";
var_dump($param1);
print "\$params = ";
var_dump($params);

$params[0] = 47;
print "\$params = ";
var_dump($params);
?>

When run this outputs...运行此输出时...

% php -f foo2.php
$param1 = NULL
$params = array(1) {
  [0]=>
  NULL
}
$param1 = int(42)
$params = array(1) {
  [0]=>
  NULL
}
$params = array(1) {
  [0]=>
  int(47)
}

Notice how $param1 was updated to 42 successfully but $params[0] was still NULL?请注意$param1如何成功更新为 42 但$params[0]仍然是 NULL? $params was only updated when we set a applied via $params[0] directly. $params仅在我们直接通过$params[0]设置应用时才更新。

Your CSV reading code (hopefully updated to use fgestcsv()) should be updating the $params[0] through $params[7] array elements directly.您的 CSV 读取代码(希望更新为使用 fgestcsv())应该直接更新$params[0]$params[7]数组元素。

I also Created A PHP module which is very less complicated, where, I upload a CSV file from Directory to MySql You can check it out here,我还创建了一个非常简单的 PHP 模块,其中,我将 CSV 文件从目录上传到 MySql 你可以在这里查看,

https://github.com/Anmolhive/PHP-CSV-Upload/ https://github.com/Anmolhive/PHP-CSV-Upload/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM