将表单值提交到数据库,php

时间:2017-05-04 14:57:43

标签: php html mysql forms csv

我目前有一张由上传的CSV构建的表单。当用户上传CSV并点击预览'按钮指向一个窗口,该窗口在可编辑的表单表格中显示整个CSV。 CSV是5个记录和229个字段。输入名称是根据行计数和列数构建的,因此使用此CSV时,它应从row1col1开始,然后转到row5col229。

我发现这些名字正如预期的那样工作,但我仍有问题。 CSV文件的SOY将有4行,有些可能有8或9.我需要找到一种方法来获取表单输入并将其全部提交到229字段登台表中。

有没有办法为一行创建数组和语句并循环它,但是实际存在多行?

这是我目前的代码:

if(isset($_POST['preview']))
{
ini_set('auto_detect_line_endings', true);


$file = $_FILES["file"]["tmp_name"];
$handle = fopen($file, "r");
$maxPreviewRows = PHP_INT_MAX;  // this will be ~2 billion on 32-bit system, or ~9 quintillion on 64-bit system
$hasHeaderRow = true;
    echo '<form method="post">';
    echo '<table>';

    if ($hasHeaderRow) {
        $headerRow = fgetcsv($handle);
        echo '<thead><tr>';
        foreach($headerRow as $value) {
            echo "<th>$value</th>";
        }
        echo '</tr></thead>';
    }

    echo '<tbody>';

    $rowCount = 0;
    while ($row = fgetcsv($handle)) {
        $colCount = 0;
        echo '<tr>';
        foreach($row as $value) {
        echo "<td><input name='row".$rowCount."col".$colCount."' type='text' value='$value' /></td>";

            $colCount++;
        }
        echo '</tr>';

        if (++$rowCount > $maxPreviewRows) {
            break;
        }
    }
    echo '</tbody></table>';
    echo '<input type=\'submit\' value=\'Submit\' >';
    var_dump($_POST);
    echo '</form>';
}
?> 

我觉得我在正确的轨道上,但我不知道如何构建元素数组或语句,以便它是一个模板,可以这么说,并为所有行循环它。

2 个答案:

答案 0 :(得分:1)

回答有关the Answer by Tom的评论:

  

您可以将表单中的vales设置为数组$ _POST [&#39;行&#39;] [&#39;列&#39;]广告然后只需计算($ _ POST [&#39; rows&#39] ;]);计算值,然后预测行中的每个值。

- 马丁

  

所以我不需要通过并声明229个元素?只需创建数组并计数,然后循环使用foreach?在这种情况下,如何在SQL中创建一个语句以插入数据库?

- 汤姆

您的表单将是一系列POST值,例如

foreach($row as $value) {
        echo "<td><input name='row[".$rowCount."][".$colCount."]' type='text' value='$value' /></td>";

            $colCount++;
        }  

然后将生成一个数组POST值,例如:

$_POST['row'][1][1] = $value;
$_POST['row'][1][2] = $value;
$_POST['row'][1][3] = $value;
...
$_POST['row'][1][229] = ...;
$_POST['row'][2][1] = ... ;
...
$_POST['row'][2][229] = ...;
...
$_POST['row'][5][229] = ...;

然后,您可以在此阵列上运行foreach循环,然后为阵列的每个键提取保存的数据的值:

$sql = $inserts = $binds = [];
foreach ($_POST['row'] as $rowValue){
    if(is_array($rowValue) && count($rowValue) > 0 ){
        foreach($rowValue as $rowData){
           /***
            * Stupidly, I had missed that row contains arrays 
            * rather than values, so you need a foreach, inside the 
            * foreach as so:
            ***/
            foreach ($rowData as $columnKey  => $columnValue){
                //$columnValue will now equal $value
                //$columnKey will be the column number (1...229)
                /***
                 * This is the area you can construct your SQL query values.
                 * db_connection is assumed to be setup.
                 ***/
                 $sql[] = "`column_name_".$columnKey."`"
                 $binder = "value".$columnKey;
                 $inserts[] = ":".$binder;
                 $binds[$binder] = $columnValue;
                 unset($binder);
            }
           unset($columnKey,$columnValue);             
       }
       unset($rowData);
       /***
        * This is the area the SQL query is set on a per row basis
        ***/
       $sqlFull = "INSERT INTO <table> (".implode(",",$sql).") VALUES(".implode(",",$inserts).")";
       $db_connection->prepare($sqlFull); 
       /***
        * EDIT: bind param MUST come after the prepare call
        ***/
       foreach($binds as $bindKey=>$bindRow){
            $db_connection->bind_param(":".$bindKey, $bindRow);
       }
       unset($bindKey,$bindRow);      
       $sql = $inserts = $binds = []; //reset arrays for next row iteration. 
       /***
        * db_connection then executes the statement constructed above
        ***/
        $db_connection->execute();
     } //close if.
}
unset($rowValue);

请注意这只是一个快速而肮脏的例子,我没有时间检查我的语法是否准确,但更多的是让您大致了解查询结构

您可以使用count()来计算$_POST数组中的行数和列数。

答案 1 :(得分:0)

我实际上想出了这个,并且这些名字按预期工作。但是,我有一个问题。有些CSV文件有5行,有些会有更多,所以我不能通过输入名称来创建静态方法。有没有办法创建一个数组和语句并循环它,但是存在多少行?

修改 当前源代码用于解决Martins的评论中提出的问题。

<?
$connect = mysqli_connect($server, $user, $pw, $db);

if ($connect->connect_error) {
die("Connection failed: " . $conn->connect_error);
}else{
echo'success!';
}

 var_dump($_POST);


     $sql = $inserts = $binds = [];
           foreach ($_POST['row'] as $rowValue){
         if(is_array($rowValue) && count($rowValue) > 0 ){
                foreach($rowValue as $columnKey  => $columnValue){
       //$columnValue will now equal $value
       //$columnKey will be the column number (1...229)
       /***
        * This is the area you can construct your SQL query values.
        * db_connection is assumed to be setup.
        ***/
        $sql[] = "`column_name_".$columnKey."`";
        $binder = "value".$columnKey;
        $inserts[] = ":".$binder;  
        $binds[$binder] = $columnValue;
        unset($binder);
    }
   unset($columnKey,$columnValue);
   /***
    * This is the area the SQL query is set on a per row basis
    ***/
   $sqlFull = "INSERT INTO staging (".implode(",",$sql).") VALUES(".implode(",",$inserts).")";
   $connect->prepare($sqlFull); 
   /***
    * EDIT: bind param MUST come after the prepare call
    ***/
   foreach($binds as $bindKey=>$bindRow){
        $connect->bind_param(":".$bindKey, $bindRow);
   }

   unset($bindKey,$bindRow); 
   var_dump($binds);   
   $sql = $inserts = $binds = []; //reset arrays for next row iteration. 
   /***
    * db_connection is then given the SQL. 
    ***/
    $connect->execute();

  echo "<p>\$sqlFull:<pre>".print_r($sqlFull,true)."</pre></p>\n";

  if(mysqli_multi_query($connect, $sqlFull)) 
  {
    echo'File submitted'; 
  } else { 
    echo "Error: " . mysqli_error($connect); 
  }
 } //close if.


}

unset($rowValue);



?>