使用Impode将HTML表单$_POST数组插入MySQL


Inserting HTML Form $_POST Array Into MySQL Using Implode

我有以下html提交表单。此表单是PHP_SELF,并将输入数据作为数组存储在$_POST中。

<html>
<body>
<form method="post" action="<?php echo htmlentities($PHP_SELF); ?>">
<fieldset>
<legend>Direct Bill Information:</legend>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" /> </br>
DB #: <input type="int" name="db_num[]" /> DB Amount: <input type="int" name="db_amnt[]" />
</fieldset>
<input type="submit" value="submit" name="submit" />
</form>
</body>
</html>

我有一个MySQL表,它有字段"db_num"answers"db_amnt",我想将数组中的所有输入数据插入到表中。我环顾四周,"内爆"似乎是最好的方法,但经过大量研究,我仍然无法使其发挥作用。然而,整个PHP执行和完成时没有出现错误,它没有显示两列的全部10行,而是只显示两列中的2行,所有条目的值都为0。这是我正在使用的代码:

$sql2 = array();
foreach($_POST as key=>$value)
{
    if(key != 'submit')
    {   
        if($value != '')
        {   
            $sql2[] = '("'.mysql_real_escape_string($value['db_num']).'", "'.$value['db_amnt'].'")';
        }   
    }
}
mysql_query('INSERT INTO ' .$tablename_db. '(db_num, db_amnt) VALUES '.implode(',', $sql2)); 

我做了一些调试,并在foreach循环中呼应了$value,结果发现它只显示了三个项Array"、"Array"answers"submit"。进一步的检查表明,我可以从提交表单中获得要显示的值的唯一方法是通过$_POST[db_num]和$_POST[db_amnt]执行foreach循环,而不仅仅是$_POST。我真的不知道它为什么这么做以及如何修复它。这是我第一次用PHP编写代码,我正在边学习边学习。我真的很感激能得到的任何帮助!

尝试这个

$db_num = $_POST['db_num'];
$db_amnt = $_POST['db_amnt'];
$items = array_combine($db_num,$db_amnt);
$pairs = array();
foreach($items as $key=>$value){
  $pairs[] = '('.intval($key).','.intval($value).')';
}
mysql_query('INSERT INTO ' .$tablename_db. '(db_num, db_amnt) VALUES '.implode(',',$pairs));

提交后,您的html表单将生成以下$_POST数组(我将制作一些示例值)。

$_POST = [
    'db_num' => ['1', '2',  '3',  '4',  '5',  '6', '7', '8', '9', '10'],
    'db_amnt' => ['100', '125', '150', '175', '200', '225', '250', '275', '300', '325']
];

换句话说,$_POST['db_num']将使$_POST['db_num'][0]一直保持1直到$_POST['db_num'][9]保持10。同样地,$_POST['db_amnt'][0]将保持100$_POST['db_amnt'][1]将保持125,依此类推。即使用户未能填写其中一个字段,空字段仍将被提交,并且该值将是一个零宽度字符串(空字符串)。

通过结构化表单数据来提供这样一组干净、即时可用/可遍历的数据,您为自己提供了一项很好的服务。

没有必要对传入的数据进行重组(尽管伏都教建议使用array_combine())。如果需要任何额外的工作,您可能需要验证表单中每一行的"配对"值。例如,我假设您只想在给定行的db_numdb_amnt都不为空的情况下存储数据,所以我会将该检查构建到我建议的代码段中。

$conn = new mysqli($server, $user, $password, $database);
$stmt = $conn->prepare("INSERT INTO {$tablename_db} (db_num, db_amnt) VALUES (?,?)");
$stmt->bind_param("ii", $num, $amnt);  // name the two variables which will pass integer values where the ?'s are located
foreach ($_POST['db_num'] as $index => $num) {
    $amnt = $_POST['db_amnt'][$index];
    if (strlen($num) && strlen($amnt)) {
        $stmt->execute();  // only INSERT qualifying rows
    }
}

请注意,如果您的db_amnt值有小数位(它们是浮点数),那么您可以将bind_param()调用中的i更改为d。有些人更喜欢将所有值声明为s(字符串)的最简单方法,但我喜欢在处理可预测的用户输入时控制它。

下面是迭代技术的演示。

如果要进行其他验证检查,只需将它们添加到我的if表达式中即可。

如果你想享受个人成功检查,你可以立即在execute()下写一些东西来引用受影响的行。

重新使用准备好的语句是使用mysqli完成该过程的两种方式之一。另一种是构建一个包含所有行的、包罗万象的INSERT查询,但这需要更多的准备工作。这两种mysqli技术是注入安全、稳定和高效的。

最后,一些开发人员会说,在尝试访问子数组之前,应该检查每个索引是否真的存在;其他开发人员坚持认为,没有必要处理用户故意入侵html生成的通知。我将由个别研究人员决定他们是否希望在迭代之前和迭代时进行isset()调用。