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

将表单值提交到数据库,php,php,html,mysql,forms,csv,Php,Html,Mysql,Forms,Csv,我目前有一个表单是从上传的CSV构建的。当用户上传CSV并点击“预览”按钮时,它将指向一个窗口,该窗口在可编辑的表格中显示整个CSV。CSV是5条记录和229个字段。输入名称是根据行计数和列计数生成的,因此使用此CSV,它应该从row1col1开始,然后转到row5col229 我发现这些名字都是这样工作的,正如预期的那样,但是我仍然有一个问题。一些CSV文件将有4行,一些可能有8或9行。我需要找到一种方法来接受表单输入并将其全部提交到229字段暂存表中 有没有一种方法可以为一行创建数组和语句,

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

我发现这些名字都是这样工作的,正如预期的那样,但是我仍然有一个问题。一些CSV文件将有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>';
}
?> 
if(isset($\u POST['preview']))
{
ini设置(“自动检测线结束”,true);
$file=$\u文件[“文件”][“tmp\u名称”];
$handle=fopen($file,“r”);
$maxPreviewRows=PHP_INT_MAX;//在32位系统上大约是20亿,在64位系统上大约是90亿
$hasHeaderRow=true;
回声';
回声';
如果($hasHeaderRow){
$headerRow=fgetcsv($handle);
回声';
foreach($headerRow作为$value){
回显“$value”;
}
回声';
}
回声';
$rowCount=0;
而($row=fgetcsv($handle)){
$colCount=0;
回声';
foreach(行作为$value){
回声“;
$colCount++;
}
回声';
如果(++$rowCount>$maxPreviewRows){
打破
}
}
回声';
回声';
变量转储($\u POST);
回声';
}
?> 

我觉得我的思路是正确的,但我不知道如何构建元素数组或语句,使其成为一个模板,可以说,并对所有行循环它

我真的弄明白了这一点,而且名字也按预期工作。然而,我有一个问题。一些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);



?>

回答以下评论:

您可以将表单中的值设置为数组$\u POST['rows']['columns']ad,然后只需计数($\u POST['rows']);对值进行计数,然后对行中的每个值进行foreach

--马丁


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

--汤姆

您的表单将是一个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']作为$rowValue){
if(is_数组($rowValue)&&count($rowValue)>0){
foreach($rowValue作为$rowData){
/***
*愚蠢的是,我错过了包含数组的那一行
*而不是值,因此需要在
*因此:
***/
foreach($rowdataas$columnKey=>$columnValue){
//$columnValue现在将等于$value
//$columnKey将是列编号(1…229)
/***
*这是可以构造SQL查询值的区域。
*假设已设置db_连接。
***/
$sql[]=“`column\u name.'$columnKey.`”
$binder=“value”。$columnKey;
$inserts[]=“:”$binder;
$binds[$binder]=$columnValue;
未结算($活页夹);
}
未设置($columnKey,$columnValue);
}
未设置($行数据);
/***
*这是SQL查询按行设置的区域
***/
$sqlFull=“INSERT-INTO(“.introde(“,”,$sql)。”)值(“.introde(“,”,$inserts)。”);
$db_连接->准备($sqlFull);
/***
*编辑:bind参数必须在prepare调用之后
***/
foreach($binds as$bindKey=>$bindRow){
$db_connection->bind_参数(“:”$bindKey,$bindRow);
}
未设置($bindKey,$bindRow);
$sql=$inserts=$binds=[];//为下一行迭代重置数组。
/***
*db_连接然后执行上面构造的语句
***/
$db_连接->执行();
}//如果需要,请关闭。
}
未结算(rowValue);

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


您可以使用
count()
$\u POST
数组中的行和列进行计数

您可以将表单中的值设置为数组
$\u POST['rows']['columns']
ad,然后只需
count($\u POST['rows'])
对值进行计数,然后对行中的每个值进行
foreach
,这样我就不需要遍历并声明229个元素了?只需创建数组并计数,然后使用foreach循环?在这种情况下,我将如何在SQL中创建一条语句以插入数据库?这是一个相当大的问题;您可以使用foreach循环构造sqlinsert的参数,然后在循环之后运行insert。在SOOk上会有很多参考资料,我想我理解。我将对此进行一些研究,谢谢。恐怕这需要一些编辑,因为在设置
->prepare
@TomN之前,您不能
->bindparam
。我已经更新了答案,所以绑定参数现在应该可以正常工作了。我必须高度鼓励你们研究准备好的声明,并充分利用
$_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] = ...;
$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);