【问题标题】:Insert multiple rows to database from HTML form using MySQLi使用 MySQLi 从 HTML 表单向数据库插入多行
【发布时间】:2015-01-19 18:10:07
【问题描述】:

我正在尝试制作一个使用数组的表单,以便在提交和处理后将多行插入到我的数据库中。我的主程序比下面的更复杂,但我无法让它工作,所以我决定创建一个简单的小程序来更好地理解基本语法,然后将这些技术应用于主程序。我已经使用折旧的 MySQL 让它工作,但是将它转换为 MySQLi 会导致问题,我想知道我是否可以得到帮助。

我的表单是这样设置的

<html>
<title>multi row insert test form</title>
<body>
<table>
<form action="process2.php" method="post">
<tr>
<th>forename</th>
<th>surname</th>
<th>level</th>
</tr>
<tr>
<td><input type="text" name="fname[]"></td>
<td><input type="text" name="sname[]"></td>
<td> 
<select name="level[]">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select> 
</td>
</tr>
<tr>
<td><input type="text" name="fname[]"></td>
<td><input type="text" name="sname[]"></td>
<td> 
<select name="level[]">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select> 
</td>
</tr>
<tr>
<td><input type="submit" name="submit" value="Submit"></td>
</tr>
</form>
</table>
</body>
</html>

使用MySQLi更新数据库的php页面如下

<?php
include 'dbconnect2.php';
$fname = $_POST['fname'];
$sname = $_POST['sname'];
$level = $_POST['level'];


if ($stmt = $mysqli->prepare("INSERT INTO people (fname, sname, level) values (?, ?, ?)")) {

$stmt->bind_param('ssi', $fname, $sname, $level);

for ($i=0; $i<2; $i++)
{
$fname[$i] = $fname;
$sname[$i] = $sname;
$level[$i] = $level;

$stmt->execute();
echo "Done";
}

$stmt->close();
}
?>

【问题讨论】:

    标签: php html mysqli


    【解决方案1】:

    或者,减少对现有代码的重写:

    $fnames = $_POST['fname'];
    $snames = $_POST['sname'];
    $levels = $_POST['level'];
    
    $stmt = $mysqli->prepare("INSERT INTO people (fname, sname, level) values (?, ?, ?)")
    
    for ($i=0; $i<count($fnames); $i++) {
        $fname = $fnames[$i];
        $sname = $snames[$i];
        $level = $levels[$i];
        $stmt->bind_param('ssi', $fname, $sname, $level);
    
        $stmt->execute();
    }
    echo "Done";
    
    $stmt->close();
    

    【讨论】:

    • bind_param() 不需要迭代 -- 将该行移到 for() 行上方。
    【解决方案2】:

    看起来您只是在循环中颠倒了声明语法。

    另外,连接 include 后的前三个声明不是必需的。

    include 'dbconnect2.php';
    $stmt = $mysqli->prepare("INSERT INTO people (fname, sname, level) VALUES (?, ?, ?)");
    $stmt->bind_param('ssi', $fname, $sname, $level);
    foreach ($_POST['fname'] as $index => $fname) {
        $sname = $_POST['sname'][$index];
        $level = $_POST['level'][$index];
        $stmt->execute();
    }
    

    【讨论】:

    • 我会避免将prepare() 放在if 语句中。它没有增加任何好处并且正在创建一个非常混乱的代码。
    • 嗯,这样做的好处是在绑定或执行未成功初始化的语句时不会发生后续错误。在其他答案中,我包括对绑定和执行的失败检查。但是,我真的不想进入关于所有开发人员应该如何在每个项目中记录错误的冗长讨论。我同意为每个检查点编写条件会使脚本更加臃肿且难以阅读。我将删除条件。
    【解决方案3】:

    试试这个。您需要迭代所有帖子数据,并将它们绑定到 IN 循环中。

    include 'dbconnect2.php';
    for ($i = 0; $i < count($fname); $i++) {
        $stmt = $mysqli->prepare("INSERT INTO people (fname, sname, level) values (?, ?, ?)");
        $stmt->bind_param('ssi', $_POST["fname"][$i], $_POST["sname"][$i], $_POST["level"][$i]);
        $stmt->execute();
    }
    echo "Done";
    $stmt->close();
    

    【讨论】:

    • 您提供的代码不会向数据库提交任何内容,但会出现错误“在非对象上调用成员函数 close()”
    • 不要迭代地实例化准备好的语句——你只需要一个(可以而且应该重复使用)。如果您覆盖绑定变量,就像在 Alexanders 的回答中一样,您将不需要对 bind_param() 进行迭代调用。
    猜你喜欢
    • 1970-01-01
    • 2016-06-20
    • 2017-06-14
    • 1970-01-01
    • 2019-09-03
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多