无法在mysql中的fgetcsv上完成

时间:2017-04-08 19:41:28

标签: php mysql fgetcsv

<?php
header('Content-Type: text/html; charset=utf-8');
$servername = "localhost";
$username = "root";
$password = "abc";
$dbname = "project";

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 
$sql = "TRUNCATE TABLE datapack";
mysqli_query($conn,$sql);

if(isset($_POST['submit']))
{
     $fname = $_FILES['sel_file']['name'];
     echo 'upload file name: '.$fname.' ';
     $chk_ext = explode(".",$fname);

     if(strtolower(end($chk_ext)) == "csv")
     {
         $filename = $_FILES['sel_file']['tmp_name'];
         $handle = fopen($filename, "r");
         $head = fgetcsv($handle);
         while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
         {
            $sql= "INSERT into datapack(id,nickname,time,msg) values('$data[0]','$data[1]','$data[2]','$data[3]')";
            mysqli_query($conn,$sql);
            echo "Error: ". $conn->error;
          }
        echo "Success!";                  
     }

     else
     {
         echo "Invalid File";
     }   
}

?>
<h1>Import CSV file</h1>
<form action='<?php echo $_SERVER["PHP_SELF"];?>' method='post' enctype="multipart/form-data">
    Import File : <input type='file' name='sel_file' size='20'>
    <input type='submit' name='submit' value='submit'>
</form>

运行文件后,我发现了一些问题:

  1. 该文件无法完全导入到mysql中(例如,当csv中有1000行时,只能导入600行),每次运行它时,导入mysql的行数都不同。

  2. 它无法回应成功。

  3. 当回显错误时,它会告诉我不正确的字符串值。我认为这是uft-8问题,但在我刚刚获得id和时间之后,情况在第1点也是如此

2 个答案:

答案 0 :(得分:0)

最重要的是,您没有逃避数据。该CSV中可能存在任何内容,从而破坏了该查询。此外,您还要限制线路长度(因此如果有长线则不会插入)并且不会检查CSV文件中的正确列数。尝试更改这些内容:

<?php
$servername = "localhost";
$username = "root";
$password = "abc";
$dbname = "project";

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 

if(isset($_POST['submit']))
{
    $fname = $_FILES['sel_file']['name'];
    echo "Uploaded file name: $fname";
    $chk_ext = explode(".",$fname);

    if(strtolower(end($chk_ext)) === "csv") {
        $sql = "TRUNCATE TABLE datapack";
        $conn->query($sql);
        $filename = $_FILES['sel_file']['tmp_name'];
        $handle = fopen($filename, "r");
        $head = fgetcsv($handle);
        $sql= "INSERT INTO datapack (id, nickname, time, msg) VALUES (?, ?, ?, ?)";
        $stmt = $conn->prepare($sql);

        while (($data = fgetcsv($handle)) !== FALSE) {
            if (count($data) < 4) {
                echo "Error, not 4 columns";
                continue;
            }
            $stmt->bind_param("isss", $data[0], $data[1], $data[2], $data[3]);
            if (!$stmt->execute()) {
                echo "Error: ". $stmt->error;
            } else {
                echo "Success!";
            }
        }
    else {
        echo "Invalid File";
    }
}

?>

<h1>Import CSV file</h1>
<form action="" method="post" enctype="multipart/form-data">
    Import File : <input type='file' name='sel_file' size='20'>
    <input type='submit' name='submit' value='submit'>
</form>

注意默认的HTML行为是发布给自己;通过不必要地添加$_SERVER["PHP_SELF"],你可以打开脚本注入攻击。

答案 1 :(得分:-1)

在小型服务器上执行1000查询可能过于昂贵。

相反,您可以进行批量插入。

$sql= "INSERT into datapack(id,nickname,time,msg) values";
$sqlArray = array();
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
    $sqlArray[] = "('$data[0]','$data[1]','$data[2]','$data[3]')";
}
$sql .= " " . implode(", ", $sqlArray);

mysqli_query($conn,$sql);
echo "Error: ". $conn->error;

但是,对于这种情况,这将是一个很好的机会开始使用begin_transaction

  

mysqli_begin_transaction

     

开始交易。需要MySQL 5.6及更高版本以及InnoDB   引擎(默认情况下启用)。有关如何的其他详细信息   MySQL事务工作,请参阅»   http://dev.mysql.com/doc/mysql/en/commit.html