【问题标题】:PHP, How can I insert my CSV file into my DatabasePHP,如何将我的 CSV 文件插入我的数据库
【发布时间】:2019-05-02 07:56:25
【问题描述】:

您好,我正在尝试这样当我将一个新的 csvfile 添加到我的文件夹中时,它将被插入到我的数据库中,但我不知道该怎么做。 这是我的 csv 文件的 eksample https://i.gyazo.com/5f97c964c12f9f38fe4f6fbc901158a8.png

我将首先展示我的 DB.php 类,我将使用它来执行我的数据。

我知道这段代码中显示了 2 个表格,用于测试我得到正确的数据

<?php

class DB extends \PDO
{
    /**
     * @var
     */
    private $host;
    /**
     * @var
     */
    private $user;
    /**
     * @var
     */
    private $pass;
    /**
     * @var PDO
     */
    private $conn;
    /**
     * @var
     */
    private $query;
    /**
     * @var bool
     */
    private $debug = false;


    /**
     * @param bool $bool
     */
    public function debug($bool = true)
    {
        $this->debug = $bool;
    }

    /**
     * @param $sql
     */
    private function setQuery($sql)
    {
        $this->query = $this->prepare($sql);
    }

    /**
     * DB constructor.
     * @param $dbhost
     * @param $dbuser
     * @param $dbpass
     * @param array $options
     */
    public function __construct($dbhost, $dbuser, $dbpass, $options = [])
    {
        try {
            $this->conn = parent::__construct($dbhost, $dbuser, $dbpass, $options);
        } catch (\PDOException $e) {
            print "Fejl!: " . $e->getMessage() . "<br/>";
            die();
        }

    }


    /**
     * @param string $sql
     * @param bool $params
     * @param int|mixed|null $returnType
     * @return mixed
     */
    public function query($sql, $params = false, $returnType = \PDO::FETCH_OBJ)
    {
        $this->setQuery($sql);
        $this->execute($params);
        $this->count = $this->query->rowCount();

        return $this->query->fetchAll($returnType);
    }

    /**
     * @param $params
     */
    private function execute($params)
    {
        if($params){
            $this->query->execute($params);
        } else {
            $this->query->execute();
        }
        if($this->debug){
            echo '<pre id="debug_params">',$this->query->debugDumpParams(),'</pre>';
        }
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function single($sql, $params = false){
        $data = $this->query($sql, $params);
        if(sizeof($data) === 1){
            return $data[0];
        } else {
            return false;
        }
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function first($sql, $params = false){
        return $this->query($sql, $params)[0];
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function last($sql, $params = false){
        return $this->query($sql, $params)[$this->count - 1];
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function toList($sql, $params = false){
        return $this->query($sql, $params);
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function lastId($sql, $params = false){
        $this->query($sql, $params);
        return $this->lastInsertId();
    }
}

这是我的csvtable.php我的索引文件,这是用户将看到的。

<?php
if ($user->is_loggedin() == true) {

// File selector
    $path = "./assets/csv"; 

    $latest_ctime = 0;
    $latest_filename = '';    

    $d = dir($path);
    while (false !== ($entry = $d->read())) {
    $filepath = "{$path}/{$entry}";
    // could do also other checks than just checking whether the entry is a file
        if (is_file($filepath) && filectime($filepath) > $latest_ctime){
            $latest_ctime = filectime($filepath);
            $latest_filename = $entry;
        }
    }

// File selector end

    echo'<h1 class="text-center">CSV Table</h1>';
    echo'<h6 class="text-center">'.$latest_filename.'</h6>';
    echo '<table class=" table table-striped table-bordered table-hover" style="width:100%">';
    echo'<tbody>';

    $f = fopen("$path/$latest_filename", "r");

    while (($row = fgetcsv($f, 1000, ";")) !== false) {
        //Create table using the filename as tablename, if table already exist insert data.
        $csv->createCsvTable($row);

            echo '<tr>';
            foreach ($row as $cell) {
                echo '<td>' .htmlspecialchars($cell, ENT_COMPAT). '</td>';

            }
            echo '</tr>';
    }
    fclose($f);
    echo'</tbody>';
    echo '</table>';


//csv table end
    ?><table id="example" class="table-hover  table table-striped table-bordered" style="width:100%">
    <thead>
        <tr>
            <th scope="col">Name</th>
            <th scope="col">Datum</th>
            <th scope="col">Property</th>
            <th scope="col">Criterion</th>
            <th scope="col">Type</th>
            <th scope="col">Nominal</th>
            <th scope="col">Actual</th>            
            <th scope="col">Tol-</th>                
            <th scope="col">Tol+</th>
            <th scope="col">Dev</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach($csv->getCsv() as $csv) { ?>
            <tr>
                <td><?= $csv->Name; ?></td>
                <td><?= $csv->Datum; ?></td>
                <td><?= $csv->Property; ?></td>
                <td><?= $csv->Criterion; ?></td>
                <td><?= $csv->Type; ?></td>
                <td><?= $csv->Nominal; ?></td>
                <td><?= $csv->Actual; ?></td>
                <td><?= $csv->Tolminus; ?></td>
                <td><?= $csv->Tolplus; ?></td>
                <td><?= $csv->Dev; ?></td>
            </tr>
        <?php }?>
    </tbody>

</table>
 <?php }

这是我的 CSV 类,我不知道如何编写 createCsvTable 我想要它做的是将 csv 文件数据插入到我创建的表中。

<?php

class Csv extends \PDO {

private $db = null;



/**
 * Settings constructor.
 */
public function __construct($db)
{
    $this->db = $db;
}

/**
 * Menu & Admin Menu
 * @return mixed
 */

public function getCsv()
{
    return $this->db->toList("SELECT * FROM Test");
}

   public function createCsvTable()
    {
        return $this->db->toList("CREATE TABLE IF NOT EXISTS Test(
            id int (11),
            Name VARCHAR(30), 
            Datum VARCHAR(30), 
            Property VARCHAR(30), 
            Criterion VARCHAR(30), 
            Type VARCHAR(30), 
            Nominal DECIMAL(10,2), 
            Actual DECIMAL(10,2), 
            Tolminus DECIMAL(10,2), 
            Tolplus DECIMAL(10,2), 
            Dev DECIMAL(10,2)
          );
          /* INSERT QUERY */
          INSERT INTO Testeses(
            id, Name, Datum, Property, Criterion, Type, 
            Nominal, Actual, Tolminus, Tolplus, Dev
          ) 
          VALUES 
            (
              ?,?,?,?,?,?, 
              ?,?,?,?,?
            );");
    }
}

我知道如果我更换了 ?它会插入一些实际数据,但我需要它来自 csv 文件。这是主要问题

所以为了清楚起见,我的问题是“如何将我的 csv 文件中的数据插入到我的数据库中?”

如果您知道如何以文件名命名表格,我将不胜感激。

【问题讨论】:

  • 好吧,但我不需要将文件名存储在我的数据库中我需要将文件作为我的数据库中的表
  • 你试过什么?确切的问题是什么?编写一个从文件中读取数据并运行正确查询的循环并不难
  • 正如@NicoHaase 所说。循环遍历 csv 文件,一一读取行并将其插入到您的数据库中。
  • 我试图做的是,起初我只想能够在我的网站上看到该文件,但由于我现在需要使用它,所以我需要将它存储在我的数据库中,所以我可以使用它的数据。但我不知道该怎么做。

标签: php mysql csv pdo


【解决方案1】:

经过一些测试和挠头后,我找到了一个不错的解决方案。这是做什么的

  1. 它会查看目录。
  2. 找到最新的文件。
  3. 创建最新文件的副本并将其发送到其他目录。
  4. 使用 CSV.php 文件创建一个以最新文件命名的表。
  5. 然后它会打开复制的文件并获取数据。
  6. 根据数据创建一个数组(据我所知)。
  7. 统计数据。
  8. 用字符串连接数组元素。
  9. 将该字符串拆分为“单元格/单个值”
  10. 然后将数据插入到表中。

给那些可能想要使用它的人的注释。注意这个“;”你 可能必须将其更改为“,”,具体取决于您的文件的方式 分开。我的文件使用“;”分隔我正在使用 utf8_encode 这样我就可以使用特殊字符,例如 ÆØÅ 您必须进行的更改位于此期间。

while ($getdata = fgetcsv($openfile, 1000, ";")) {
$getdata = array_map("utf8_encode", $getdata);
$total = count($getdata);
//    echo "<b>Row no:-</b>$row\n";   
//    echo "<b>Total fields in this row:-</b>$total\n";
$row++;
for ($c=0; $c < $total; $c++) {
    $csvdata = implode(";", $getdata);
    $fncsvdata = explode(";", $csvdata);
}

我还创建了一个表格来显示我如何在我的网站上获得输出。

这是答案

这是用户看到的文件。在我的例子中,它叫做csvtable.php

<?php
    // File selector
    $path = "./assets/csv"; 
    $sourcepath = "assets/csv"; 
    $copy = "assets/proceskontrol-csv";
    $latest_ctime = 0;
    $latest_filename = '';    

    $d = dir($path);
    while (false !== ($entry = $d->read())) {
    $filepath = "{$path}/{$entry}";
    // could do also other checks than just checking whether the entry is a file
        if (is_file($filepath) && filectime($filepath) > $latest_ctime){
            $latest_ctime = filectime($filepath);
            $latest_filename = $entry;
        }
    }
    if (1+1 == 2){
        copy("$sourcepath/$latest_filename","$copy/$latest_filename");
        $csv->createCsvTable($latest_filename);
        $row = 1;
        if (($openfile = fopen("$copy/$latest_filename", "r")) !== FALSE) {
            while ($getdata = fgetcsv($openfile, 1000, ";")) {
                $getdata = array_map("utf8_encode", $getdata);
                $total = count($getdata);
                //    echo "<b>Row no:-</b>$row\n";   
                //    echo "<b>Total fields in this row:-</b>$total\n";
                $row++;
                for ($c=0; $c < $total; $c++) {
                    $csvdata = implode(";", $getdata);
                    $fncsvdata = explode(";", $csvdata);
                }
                $csv->insertCsvTable($latest_filename ,$fncsvdata);
            }
        }
    }
    echo'<h1 class="text-center">CSV Table</h1>';
    echo'<h6 class="text-center">'.$latest_filename.'</h6>';
    echo '<table class=" table table-striped table-bordered table-hover">';
    echo'<tbody>';
?>

    <table class="table-hover table table-striped table-bordered">
    <thead>
        <tr>   
            <th scope="col">id</th>
            <th scope="col">Name</th>
            <th scope="col">Datum</th>
            <th scope="col">Property</th>
            <th scope="col">Criterion</th>
            <th scope="col">Type</th>
            <th scope="col">Nominal</th>
            <th scope="col">Actual</th>            
            <th scope="col">Tol-</th>                
            <th scope="col">Tol+</th>
            <th scope="col">Dev</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach($csv->getCsv($latest_filename) as $csv) { ?>
            <tr>
                <td><?= $csv->id; ?></td>
                <td><?= $csv->Name; ?></td>
                <td><?= $csv->Datum; ?></td>
                <td><?= $csv->Property; ?></td>
                <td><?= $csv->Criterion; ?></td>
                <td><?= $csv->Type; ?></td>
                <td><?= $csv->Nominal; ?></td>
                <td><?= $csv->Actual; ?></td>
                <td><?= $csv->Tolminus; ?></td>
                <td><?= $csv->Tolplus; ?></td>
                <td><?= $csv->Dev; ?></td>
            </tr>
        <?php }?>
    </tbody>
</table>

这是我的数据库类文件DB.php。在CSV.php中使用了很多

<?php
class DB extends \PDO
{
    /**
     * @var
     */
    private $host;
    /**
     * @var
     */
    private $user;
    /**
     * @var
     */
    private $pass;
    /**
     * @var PDO
     */
    private $conn;
    /**
     * @var
     */
    private $query;
    /**
     * @var bool
     */
    private $debug = false;


    /**
     * @param bool $bool
     */
    public function debug($bool = true)
    {
        $this->debug = $bool;
    }

    /**
     * @param $sql
     */
    private function setQuery($sql)
    {
        $this->query = $this->prepare($sql);
    }

    /**
     * DB constructor.
     * @param $dbhost
     * @param $dbuser
     * @param $dbpass
     * @param array $options
     */
    public function __construct($dbhost, $dbuser, $dbpass, $options = [])
    {
        try {
            $this->conn = parent::__construct($dbhost, $dbuser, $dbpass, $options);
        } catch (\PDOException $e) {
            print "Fejl!: " . $e->getMessage() . "<br/>";
            die();
        }

    }


    /**
     * @param string $sql
     * @param bool $params
     * @param int|mixed|null $returnType
     * @return mixed
     */
    public function query($sql, $params = false, $returnType = \PDO::FETCH_OBJ)
    {
        $this->setQuery($sql);
        $this->execute($params);
        $this->count = $this->query->rowCount();

        return $this->query->fetchAll($returnType);
    }

    /**
     * @param $params
     */
    private function execute($params)
    {
        if($params){
            $this->query->execute($params);
        } else {
            $this->query->execute();
        }
        if($this->debug){
            echo '<pre id="debug_params">',$this->query->debugDumpParams(),'</pre>';
        }
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function single($sql, $params = false){
        $data = $this->query($sql, $params);
        if(sizeof($data) === 1){
            return $data[0];
        } else {
            return false;
        }
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function first($sql, $params = false){
        return $this->query($sql, $params)[0];
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function last($sql, $params = false){
        return $this->query($sql, $params)[$this->count - 1];
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function toList($sql, $params = false){
        return $this->query($sql, $params);
    }

    /**
     * @param $sql
     * @param bool $params
     * @return mixed
     */
    public function lastId($sql, $params = false){
        $this->query($sql, $params);
        return $this->lastInsertId();
    }
}

这是CSV.php,这是我创建表并插入数据的地方。 (sql调用)

<?php
class Csv extends \PDO {

    private $db = null;



    /**
     * Settings constructor.
     */
    public function __construct($db)
    {
        $this->db = $db;
    }

    /**
     * Menu & Admin Menu
     * @return mixed
     */

    public function getCsv($latest_filename)
    {
        return $this->db->toList("SELECT * FROM `$latest_filename`");
    }

    public function createCsvTable($latest_filename)

    {
        return $this->db->toList("CREATE TABLE IF NOT EXISTS `$latest_filename`(
            id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            Name VARCHAR(50), 
            Datum VARCHAR(50), 
            Property VARCHAR(50), 
            Criterion VARCHAR(50), 
            Type VARCHAR(50), 
            Nominal DECIMAL(10,2), 
            Actual DECIMAL(10,2), 
            Tolminus DECIMAL(10,2), 
            Tolplus DECIMAL(10,2), 
            Dev DECIMAL(10,2))
        ");
    }
    public function insertCsvTable($latest_filename ,$fncsvdata)
    {
        return $this->db->toList("INSERT INTO `$latest_filename` (`Name`,  `Datum`, `Property`, `Criterion`, `Type`, `Nominal`, `Actual`,`Tolminus`,`Tolplus`,`Dev`)
        VALUES (:Name, :Datum, :Property, :Criterion, :Type, :Nominal, :Actual, :Tolminus, :Tolplus, :Dev)",
            [
            ':Name' => $fncsvdata[0],
            ':Datum'=> $fncsvdata[1],
            ':Property'=> $fncsvdata[2],
            ':Criterion'=> $fncsvdata[3],
            ':Type'=> $fncsvdata[4],
            ':Nominal'=> $fncsvdata[5],
            ':Actual'=> $fncsvdata[6],
            ':Tolminus'=> $fncsvdata[7],
            ':Tolplus'=> $fncsvdata[8],
            ':Dev'=> $fncsvdata[9]
            ]);
    }
}

我真的希望有人可以使用它。

【讨论】:

    【解决方案2】:

    CSV 是一种“逗号分隔值”格式,在您的数据库中有“索引”。因此,要保存一个 csv 文件,您需要加载它,遍历每一行,然后使用查询插入它。所以你的代码可能看起来像这样:

    $stmt = $pdo->prepare('INSERT INTO Testeses(id, Name, Datum, ...)
                           VALUES (
                                   :id, :name, :date, ...
                           );');
    foreach($csvLines as $line) {
        $stmt->bindValue(':id', $line[0]);
        $stmt->bindValue(':name', $line[1]);
        $stmt->bindValue(':date', $line[2]);
        $stmt->execute();
    }
    

    您需要知道特定值位于哪个位置。

    【讨论】:

    • 要将表命名为与 csv 文件相同的名称,您可以将替换查询中的表名称替换为用于加载文件的“$latest_filename”变量
    • 插入数据或表名有问题吗?将整个功能发布为新答案...
    • 我的表中的数据没有插入有问题,表已创建但没有数据。
    • 如果您这样做将不胜感激 :)
    【解决方案3】:

    我在下面发布了一个解决方案。也许阅读本文以了解 PDO 和 PreparedStatements,以便了解如何将它们绑定到列。 您需要更改方法执行和准备您的 pdo 对象,因为我不知道您是如何管理它来执行语句的。

    public function createCsvTable($file_name, $lines)
        {
            $tableCreation = "CREATE TABLE IF NOT EXISTS " . $file_name . "(
                id int (11),
                Name VARCHAR(30), 
                Datum VARCHAR(30), 
                Property VARCHAR(30), 
                Criterion VARCHAR(30), 
                Type VARCHAR(30), 
                Nominal DECIMAL(10,2), 
                Actual DECIMAL(10,2), 
                Tolminus DECIMAL(10,2), 
                Tolplus DECIMAL(10,2), 
                Dev DECIMAL(10,2)
              );";
              $stmt = execute($tableCreation);
    
              $insertion = "INSERT INTO " . $file_name . "(
                id, Name, Datum, Property, Criterion, Type, 
                Nominal, Actual, Tolminus, Tolplus, Dev
              ) 
              VALUES 
                (
                  ?,?,?,?,?,?, 
                  ?,?,?,?,?
                );");
             $stmt = prepare($insertion);
             foreach ($lines as $line) {
                 $stmt->bindParam(1, $line[0]);
                 // do for every parameter
                 $stmt->execute();
             }
    
        }
    

    【讨论】:

    • 然后把值改成 :id :name 等等?
    • 那将是我的首选方式,是的。
    • 哦,好吧,我会调查的。我已经将我的数据库类添加到问题中,因为你说你不明白我是如何执行我的数据的。
    猜你喜欢
    • 2014-05-03
    • 1970-01-01
    • 2017-03-08
    • 2021-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 2020-11-12
    相关资源
    最近更新 更多