我目前有一张由上传的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>';
}
?>
我觉得我在正确的轨道上,但我不知道如何构建元素数组或语句,以便它是一个模板,可以这么说,并为所有行循环它。
答案 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);
?>