如果我只输入1条记录。它只保存数据库中的1条记录,这很好。 但如果我把两个相同字段的记录。它在数据库中保存了多条记录,只有两条记录。我做错了什么?
<td>1.<input name='Description[]' type='text' required></td>
<td><input type='text' name='Unit[]' placeholder='eg. reams,pcs,box' required></td>
<td><input type='number' name='Quantity[]' min='1' required></td>
<td><input type='number' name='Cost[]' min='1' required></td>
</tr>
我有一个可以再次添加这些字段的脚本。
以下是代码:
foreach ($_POST["Description"] as $Description )
{
foreach ($_POST["Unit"] as $Unit)
{
foreach ($_POST["Quantity"] as $Quantity)
{
foreach ($_POST["Cost"] as $Cost)
{
$array = array($Description,$Unit,$Quantity,$Cost);
odbc_exec($conn, "INSERT INTO MRF_Request (Qty,Unit,Description,Cost) VALUES
('$Quantity' , '$Unit' , '$Description' , '$Cost')");
}
}
}
}
答案 0 :(得分:1)
您只能循环使用一个字段,并使用其他索引来获取适当的数据:
foreach ($_POST["Description"] as $index => $val )
{
$Description = $_POST['Description'][$index];
$Unit = $_POST['Unit'][$index];
$Quantity = $_POST['Quantity'][$index];
$Cost = $_POST['Cost'][$index];
$array = array($Description, $Unit, $Quantity, $Cost);
$query = "
INSERT INTO MRF_Request (Qty, Unit, Description, Cost)
VALUES ('$Quantity', '$Unit', '$Description', '$Cost')
";
odbc_exec($conn, $query);
}
您还应考虑清理$_POST
数据,以确保系统安全可靠。
答案 1 :(得分:0)
不仅需要将迭代技术修改为单循环并使用要迭代的子数组的索引,而且还必须保护您的查询,使其免受提交值中的单引号引起的注入攻击和破坏。 / p>
我从没使用过odbc_
,但它似乎与PDO的执行类似。
使用单个prepared statement并在循环内执行。
$stmt = odbc_prepare($conn, "INSERT INTO MRF_Request (Qty, Unit, Description, Cost) VALUES (?, ?, ?, ?)");
foreach ($_POST['Quantity'] as $index => $qty) {
odbc_execute($stmt, [$qty, $_POST['Unit'][$index], $_POST['Description'][$index], $_POST['Cost'][$index]]);
}
根据https://www.php.net/manual/en/function.odbc-execute.php
被警告parameter_array中任何以单引号开头和结尾的参数都将被当作要读取的文件的名称,并作为适当占位符的数据发送到数据库服务器。
由于上述原因和其他原因(例如维护干净的数据),您应该先验证/清除值,然后再保存它们。
一种防止不必要的文件读取的方法是对以下任何符合条件的值调用替换:
$value = preg_replace('~^('+)(.*)\1$~', '$2', $value);
这将确保任何值都不会以单引号开头和结尾。 (Demo)
Description
是“最不完整”的输入字段,您应该对它进行彻底的清理。
Unit
看起来像是一个值,在其中声明可接受值的白名单将是理想的选择。也许考虑用户界面中的<select>
字段-无论哪种方式都应该进行验证。
Quantity
看起来像是整数,因此您可以调用ctype_digit()
并具有最小/最大配额。
Cost
可能是浮点数。根据您的首选格式,有几种验证方法。