【问题标题】:PHP Array inserting too many records in the databasePHP数组在数据库中插入太多记录
【发布时间】:2015-12-25 15:52:51
【问题描述】:

如果我只输入 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 都嵌套。有一个 for 循环就足够了
  • 如果该表单将被公开使用,那么您真的必须转义输入以防止 sql 注入!

标签: php arrays post odbc sql-insert


【解决方案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 数据,以确保系统安全可靠。

【讨论】:

  • 非常感谢,我的数组很差。我也会研究一下消毒的事情并听取你的建议。
【解决方案2】:

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

我没用过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 看起来像是声明可接受值的白名单的理想值。或许可以考虑 UI 中的 &lt;select&gt; 字段——无论哪种方式都应该进行验证。

  • Quantity 看起来像一个整数,因此您可以调用ctype_digit() 和/或具有最小/最大允许值。

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

【讨论】:

    猜你喜欢
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多