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