PHP 数组在数据库中插入了太多记录

PHP Array inserting too many records in the database

如果我只输入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')");
                }
            }
        }
    }

您可以只遍历一个字段并为其他字段使用索引以获取适当的数据:

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 数据,以使系统安全可靠。

您不仅需要将迭代技术修改为单循环并使用正在迭代的子数组的索引,还必须保护您的查询免受注入攻击和由于提交值中的单引号引起的破坏.

没用过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

Any parameters in parameter_array which start and end with single quotes will be taken as the name of a file to read and send to the database server as the data for the appropriate placeholder.

出于上述原因和其他原因(如维护干净的数据),您应该 valid/sanitize 值才能保存它们。

防止不必要的文件读取的一种方法是调用任何符合条件的值的替换,如下所示:

$value = preg_replace('~^('+)(.*)$~', '', $value);

这将确保任何值都不会以单引号开头和结尾。 (Demo)

  • Description 是 "loosest" 输入字段,你应该相当无情地清理它。

  • Unit 看起来像一个值,其中声明可接受值的白名单是理想的。也许考虑 UI 中的 <select> 字段——无论哪种方式都应该进行验证。

  • Quantity 看起来像一个整数,因此您可能需要 ctype_digit() 和/或有 minimum/maximum 津贴。

  • Cost 可能是一个浮点数。根据您的首选格式,有多种验证技术。