【问题标题】:Import CSV, exclude first row导入 CSV,排除第一行
【发布时间】:2012-08-29 09:16:29
【问题描述】:

我现在可以很好地导入我的 csv,除了一件事,我如何让导入忽略第一行中的数据?员工将上传与第一行中的列名相同的格式。

if (isset($_POST['submit'])) {
    if (is_uploaded_file($_FILES['filename']['tmp_name'])) {
        echo "<h1>" . "File " . $_FILES['filename']['name'] . " uploaded successfully." . "</h1>";
        echo "<h2>Displaying contents:</h2>";
        readfile($_FILES['filename']['tmp_name']);
    }

    //Import uploaded file to Database
    $handle = fopen($_FILES['filename']['tmp_name'], "r");

    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $import = "INSERT into tictoc(employee,taskname,tasktime,sessiontime,sessionstart,sessionend,sessionnotes) values('" . $userinfo['first_name'] . " " . $userinfo['last_name'] . "','$data[0]','$data[1]','$data[2]','$data[3]','$data[4]','$data[5]')";

        mysql_query($import) or die(mysql_error());
    }

    fclose($handle);

    print "Import done";
}

【问题讨论】:

  • 您的代码容易受到 SQL 注入的攻击。您确实应该使用prepared statements,将变量作为参数传递给其中获得 SQL 评估。如果你不知道我在说什么,或者如何解决它,请阅读Bobby Tables 的故事。特别是,上传的文件可能包含将被注入到您的INSERT 语句中的 SQL。

标签: php mysql csv import-from-excel


【解决方案1】:

只需设置一个变量$i = 0 然后只在$i = 1 或更多时插入

if (isset($_POST['submit'])) {
    $i=0; //so we can skip first row

    if (is_uploaded_file($_FILES['filename']['tmp_name'])) {
        echo "<h1>" . "File ". $_FILES['filename']['name'] ." uploaded successfully." . "</h1>";
        echo "<h2>Displaying contents:</h2>";
        readfile($_FILES['filename']['tmp_name']);
    }

    //Import uploaded file to Database
    $handle = fopen($_FILES['filename']['tmp_name'], "r");

    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        if($i>0) {
            $import="INSERT into tictoc(employee,taskname,tasktime,sessiontime,sessionstart,sessionend,sessionnotes) values('".$userinfo['first_name']." ".$userinfo['last_name']."','$data[0]','$data[1]','$data[2]','$data[3]','$data[4]','$data[5]')";

            mysql_query($import) or die(mysql_error());
        }
        $i++;
    }

    fclose($handle);

    print "Import done";
}

【讨论】:

  • 第一行虽然包含标题内容
  • @Hector 但你的问题是如何跳过第一行。查看更新的答案
  • 这实际上是一种不好的形式,在循环中进行条件检查可以通过在循环之前简单地读取一行来处理。不需要计数器或循环条件。
【解决方案2】:

您可以简单地使用 MySQL 的 LOAD DATA INFILE 命令,它将是 considerably faster,而不是将 CSV 解析为 PHP,为每条记录构造一个 INSERT 语句,将其作为字符串提交给 MySQL 并让 MySQL 解析所述字符串SQL(有 SQL 注入的风险):

LOAD DATA INFILE ? INTO TABLE tictoc
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
IGNORE 1 LINES
(tasktime, sessiontime, sessionstart, sessionend, sessionnotes)
SET employee = ?, taskname = ?

使用 PDO:

$dbh = new PDO('mysql:dbname='.$dbname, $username, $password);

if (is_uploaded_file($_FILES['filename']['tmp_name'])) {
  $qry = $dbh->prepare('
    LOAD DATA INFILE :filepath INTO TABLE tictoc
    FIELDS TERMINATED BY \',\' OPTIONALLY ENCLOSED BY \'"\'
    IGNORE 1 LINES
    (tasktime, sessiontime, sessionstart, sessionend, sessionnotes)
    SET employee = :employee, taskname = :taskname
  ');

  $qry->execute(array(
    ':filepath' => $_FILES['filename']['tmp_name'],
    ':employee' => $userinfo['first_name'],
    ':taskname' => $userinfo['last_name']
  ));
}

【讨论】:

  • 这不能被客户端计算机上的php远程使用。
  • @wlin:使用LOCAL 修饰符。
【解决方案3】:

如果你愿意,也许你可以使用这种方式:

$i=0;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    $i++;
    if($i==1) continue;

    $import="INSERT into tictoc(employee,taskname,tasktime,sessiontime,sessionstart,sessionend,sessionnotes) values('".$userinfo['first_name']." ".$userinfo['last_name']."','$data[0]','$data[1]','$data[2]','$data[3]','$data[4]','$data[5]')";

     mysql_query($import) or die(mysql_error());
}

【讨论】:

    【解决方案4】:

    不需要变量。它比这简单得多。这是一个需要最少外部代码的解决方案,并且工作得很好。试试看:

    $headers = fgetcsv($handle, 1000, ",");
    

    在获取 CSV 数据的 while() 循环之前。这会抓住标题,但不会将它们插入数据库。一旦 while 循环开始,第一行已经返回,因此将它们排除在 mysql 插入之外。最重要的是,似乎需要标题,所以这也解决了这个问题。

    最后,

    if (isset($_POST['submit'])) {
        if (is_uploaded_file($_FILES['filename']['tmp_name'])) {
            echo "<h1>" . "File " . $_FILES['filename']['name'] . " uploaded successfully." . "</h1>";
            echo "<h2>Displaying contents:</h2>";
            readfile($_FILES['filename']['tmp_name']);
        }
    
        //Import uploaded file to Database
        $handle = fopen($_FILES['filename']['tmp_name'], "r");
    
        //Grab the headers before doing insertion
        $headers = fgetcsv($handle, 1000, ",");
    
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $import = "INSERT into tictoc(employee,taskname,tasktime,sessiontime,sessionstart,sessionend,sessionnotes) values('" . $userinfo['first_name'] . " " . $userinfo['last_name'] . "','$data[0]','$data[1]','$data[2]','$data[3]','$data[4]','$data[5]')";
    
            mysql_query($import) or die(mysql_error());
        }
    
        fclose($handle);
    
        print "Import done";
    }
    

    【讨论】:

      【解决方案5】:

      你可以试试这个:

      array_shift($data);
      

      【讨论】:

        【解决方案6】:

        我已经实现了这段代码,它是经过测试的代码。我觉得用的很全

        你有一些规则:-

        1.你的 csv 文件根据数据库表名(例如:db 表名是 users 那么 csv 应该是 users.csv)

        2.您的 csv 文件的第一行应该是开始数据输入后的 db 表字段名称(例如:ID、名称等)

        3.你可以从:-http://code.google.com/p/php-csv-parser/ 下载数据源类,因为我在代码下面有要求:require_once 'CSV/DataSource.php';

        <?php
        ini_set('memory_limit','512M');
        $dbhost = "localhost";
        $dbname = "excel_import";
        $dbuser = "root";
        $dbpass = "";
        
        $conn=mysql_connect ($dbhost, $dbuser, $dbpass) or die ("I cannot connect to the database because: " . mysql_error());
        mysql_select_db($dbname) or die("Unable to select database because: " . mysql_error());
        
        
        require_once 'CSV/DataSource.php';
        
        
        $filename = "users.csv";
        $ext = explode(".",$filename);
        $path = "uploads/".$filename;
        
        $dbtable = $ext[0];
        
        import_csv($dbtable, $path);
        
        
        function import_csv($dbtable, $csv_file_name_with_path)
        {
            $csv = new File_CSV_DataSource;
            $csv->load($csv_file_name_with_path);
        
            $csvData = $csv->connect();
        
            $res='';
            foreach($csvData  as $key)
            {
                $myKey ='';
                $myVal='';
                foreach($key as $k=>$v)
                {
                    $myKey .=$k.',';
                    $myVal .="'".$v."',";
                  }
        
                $myKey = substr($myKey, 0, -1);
                $myVal = substr($myVal, 0, -1); 
                $query="insert into ".$dbtable." ($myKey)values($myVal)";
                $res=  mysql_query($query);
        
            }
        
            if($res ==1)
            {
        
                        echo "record successfully Import.";
        
            }else{
        
                        echo "record not successfully Import.";
            }
        }
        

        【讨论】:

          【解决方案7】:

          while循环之前声明一个变量

          $row=1;
          

          然后在while循环中放置这个条件

          if($row==1){
             $row++; 
             continue;
          }
          

          【讨论】:

            【解决方案8】:
            if (isset($_POST['submit'])) {
            if (is_uploaded_file($_FILES['filename']['tmp_name'])) {
                echo "<h1>" . "File " . $_FILES['filename']['name'] . " uploaded successfully." . "</h1>";
                echo "<h2>Displaying contents:</h2>";
                readfile($_FILES['filename']['tmp_name']);
            }
            
            //Import uploaded file to Database
            $handle = fopen($_FILES['filename']['tmp_name'], "r");
            fgetcsv($handle); //skip the reading of the first line from the csv file
            
            while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
                $import = "INSERT into tictoc(employee,taskname,tasktime,sessiontime,sessionstart,sessionend,sessionnotes) values('" . $userinfo['first_name'] . " " . $userinfo['last_name'] . "','$data[0]','$data[1]','$data[2]','$data[3]','$data[4]','$data[5]')";
            
                mysql_query($import) or die(mysql_error());
            }
            
            fclose($handle);
            
            print "Import done";
            

            }

            【讨论】:

              猜你喜欢
              • 2014-04-16
              • 1970-01-01
              • 2023-03-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-02-05
              • 1970-01-01
              相关资源
              最近更新 更多