【问题标题】:PHP - Uploading CSV, inserting to multiple tables and displaying elsewherePHP - 上传 CSV,插入多个表格并在别处显示
【发布时间】:2017-07-15 19:04:55
【问题描述】:

我正在尝试为几个进程连接点。我有一个项目需要每天通过网页上的表单上传 CSV,该表单已经存在。每次加载 CSV 时,需要将 110 列拆分为大约 5 个不同的 MySQL 表。 CSV 将始终保持相同的顺序,但我需要确切知道 CSV 中的哪些变量/列要放入特定的表和字段中。完成此操作后,我将需要仅通过查询在其他页面上显示数据(根据页面仅显示某些内容)。我有以下代码来测试将 CSV 放入数组中:

if(isset($_POST['submit']))
{
$array = $fields = array(); $i=0;
$file = $_FILES['file']['tmp_name'];
$handle = fopen($file, "r");

if($handle){
     while (($row = fgetcsv($handle, 4096)) !== false) {
    if (empty($fields)) {
        $fields = $row;
        continue;
    }
    foreach ($row as $k=>$value) {
        $array[$i][$fields[$k]] = $value;
    }
    $i++;

}

echo "Success!";
var_dump($array);
if (!feof($handle)) {
    echo "Error: unexpected fgets() fail\n";
}
fclose($handle);
}}?>

这似乎适用于 Var_dump。然后,我分别在一个只有十个字段的小型 CSV 上使用了以下代码:

while(($filesop = fgetcsv($handle, 4096, ",")) !== false)
{

 $one = $filesop[0];
 $two = $filesop[1];
 $three = $filesop[2];
 $four = $filesop[3];
 $five = $filesop[4];
 $six = $filesop[5];
 $seven = $filesop[6];
 $eight = $filesop[7];
 $nine = $filesop[8];
 $ten = $filesop[9];

 $sql = "INSERT INTO staging (One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten) VALUES ('$one','$two', '$three','$four','$five','$six','$seven','$eight','$nine','$ten')";

 }

 if ($connect->query($sql) === TRUE) {
 echo "You database has imported successfully";
 } else {
 echo "Error: " . $sql . "<br>" . $conn->error; 
 }

我仍然对如何将这些每日上传的 CSV 的 110 个字段映射到正确的表(10 个字段到一个表,25 个到另一个,30 个到另一个等)感到困惑,以便我可以使用变量在其他页面上显示某些字段。

更新:

数组的新代码:

$table_cols[5] ="workOrderNum,lowSideMIUNum,highSideMIUNum,accountNum,custName,address,locID,utility,serialNumber,serviceName";



$tablenames = array("staging","clients","meters","tests","costs","workorders");

for($tableno = 0;$tableno < sizeof($tablenames);$tableno++){
$q = "";
$q .= "INSERT INTO ".$tablenames[$tableno]." (".$table_cols[$tableno].") VALUES (";
$cols = explode("," ,$table_cols);
$data = array();
foreach($col as $key => $fldname) {
    $data[] = "'".$coldata[$fldname]."'";
}

$q .= implode(",",$data).");";

}
echo'File submitted';

【问题讨论】:

    标签: php html mysql arrays csv


    【解决方案1】:

    请参阅下面的更新 这部分答案留给上下文

    您可以创建一个数组,其中包含要保存在每个表中的列的索引。然后为每个表运行一次插入,根据该表的数组中的索引获取列值。

    $tbl1_idxs = array(1,4,10,20,15,22);
    $tbl2_idxs = array(2,9,1,7,32,44);
    $tbl3_idxs = array(27,15,65,110,12);
    
    $q1 = "";
    $q1 .= "INSERT INTO `Table1` (`fld1`,`fld2`,`fld3`,`fld4`,`fld5`,`fld6`) ";
    $q1 .= "VALUES ('";
    $q1 .= $filesop[tbl1_idxs[0]]."','";
    $q1 .= $filesop[tbl1_idxs[1]]."','";
    $q1 .= $filesop[tbl1_idxs[2]]."','";
    $q1 .= $filesop[tbl1_idxs[3]]."','";
    $q1 .= $filesop[tbl1_idxs[4]]."','";
    $q1 .= $filesop[tbl1_idxs[5]]."');";
    
    //  Execute query #1....
    
    $q2 = "";
    $q2 .= "INSERT INTO `Table2` (`fld1`,`fld2`,`fld3`,`fld4`,`fld5`,`fld6`) ";
    $q2 .= "VALUES ('";
    $q2 .= $filesop[tbl2_idxs[0]]."','";
    $q2 .= $filesop[tbl2_idxs[1]]."','";
    $q2 .= $filesop[tbl2_idxs[2]]."','";
    $q2 .= $filesop[tbl2_idxs[3]]."','";
    $q2 .= $filesop[tbl2_idxs[4]]."','";
    $q2 .= $filesop[tbl2_idxs[5]]."');";
    
    //  Execute query #2....
    
    $q3 = "";
    $q3 .= "INSERT INTO `Table3` (`fld1`,`fld2`,`fld3`,`fld4`,`fld5`,`fld6`) ";
    $q3 .= "VALUES ('";
    $q3 .= $filesop[tbl3_idxs[0]]."','";
    $q3 .= $filesop[tbl3_idxs[1]]."','";
    $q3 .= $filesop[tbl3_idxs[2]]."','";
    $q3 .= $filesop[tbl3_idxs[3]]."','";
    $q3 .= $filesop[tbl3_idxs[4]]."','";
    $q3 .= $filesop[tbl3_idxs[5]]."');";
    
    //  Execute query #3....
    

    更新答案

    有了这么多列,我会改为按列名进行映射。有几种方法可以使其易于管理。

    在任何情况下,我都会将它们放在一个关联数组中,而不是 CSV 的每一列的硬变量名称,其中的键与表的列名称匹配。然后,您可以为每个表创建一个以逗号分隔的列列表。

    您仍然需要 203 行代码来将 CSV 字段映射到名称,但维护哪个列进入哪个表至少是可读的。并且更改将每个 CSV 列分配给变量的现有代码应该是简单的正则表达式搜索和替换。

    $coldata = array();
    $coldata['name'] = $filesop[0];
    $coldata['addr1'] = $filesop[1];
    $coldata['addr2'] = $filesop[2];
    $coldata['city'] = $filesop[3];
    $coldata['state'] = $filesop[4];
    $coldata['zip'] = $filesop[5];
    $coldata['country'] = $filesop[6];
    $coldata['gender'] = $filesop[7];
    $coldata['age'] = $filesop[8];
    $coldata['birthdate'] = $filesop[9];
    
    $table_cols = array();
    
    $table_cols[0] = "name,gender,age";
    $table_cols[1] = "name,addr1,addr2,city,state,zip";
    $table_cols[2] = "name,age,birthdate";
    
    $tablenames = array("staging","info","other");
    
    for($tableno = 0;$tableno < sizeof($tablenames);$tableno++) {
        $q = "";
        $q .= "INSERT INTO ".$tablenames[$tableno]." (".$table_cols[$tableno].") VALUES (";
        $cols = explode(",",$table_cols[$tableno]);
        $data = array();
        foreach($col as $key => $fldname) {
            $data[] = "'".$coldata[$fldname]."'";
        }
        $q .= implode(",",$data).");";
    
        //    Execute query in $q
    
    }
    

    【讨论】:

    • 啊,我还没见过那个方法。所以问题:我们创建了一个 php 文件以供参考,以防我们需要为每一列提供一个变量。基本上它有 203 行,其中我为 CSV 的每一列创建了一个变量($accountNum、$client、$etc.)。这显然是一种冗长而痛苦的方法,但它让我们可以完全控制每一个变量。您是说我会将 CSV (203) 的每一列与数组索引相关联,然后花时间将索引号映射到我已经创建的表中的正确位置?
    • 我刚刚又看了一遍,有几个小问题:首先,coldata 数组大约有 203 行长,对吧?每列只有一个长数组?然后,每个 table_cols 数组索引将用于 7 个表,因此那里将有 7 行 ([0]-[6]) 包含所有相应的名称?
    • @H.Norman:关于 table_cols 数组,没错。使用更新后的示例,您仍然为每一列映射一个变量,但由于它位于数组中,它为您提供了能够循环或索引到特定列值的额外优势。如果您的 CSV 在第一行中包含列名,则可以将该部分设为自动。
    • 我在你的另一个线程上发布了这个问题。基本上,您的列名列表应该只包含用于该表的列。不要为未保存到该表的列放置占位符(即 null)。
    • 如果不写入该列,请将其从列列表中删除。即使表格有 CSV 中没有的附加列,或者 CSV 中没有表格中的列。仅列出需要保存的特定表的那些列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    相关资源
    最近更新 更多