如何插入具有多个值的多行,但仅适用于旁边勾选复选框的项目
How to INSERT multiple rows with multiple values, but only for items that have checkboxes ticked next to them
我正在为音乐数据库编写唱片工具。
艺术家能够将曲目、单曲、EP 和专辑全部插入数据库中单独的 table。
将曲目分开 table 允许将相同的曲目附加到多首单曲、EP 和专辑中,而只需要在数据库中为该曲目提供一条记录。
这意味着单个曲目页面可以有一个自动生成的链接列表,返回到它们出现的单曲、EP 和专辑。使通过网站浏览数据库的体验更加顺畅。
我已经到了我正在编写一个工具的地步,可以将数据库中给定艺术家的任何现有曲目附加到专辑页面上。
我正在数据库中使用另一个名为 'trackconnections' 的 table 来创建曲目 table 中的曲目 ID 和专辑 [=98 中的专辑 ID 之间的关系链接=],还有一个名为 albumtracknum 的附加列,可以在专辑页面上查询时以正确的顺序输出曲目。
该工具的代码位于标记为 'Attach existing track(s) to album' 的按钮后面。该工具的代码如下:
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "includes/db_connect.pdo.php";
$artistid = $_POST["artistid"];
$albumid = $_POST["albumid"];
echo '<strong>Select each track you would like to add to this album below and type in the track number you want it to have on the album in the box underneith the name of each selected track.</strong><br><br>';
$stmt = $pdo->query("SELECT * FROM track WHERE artist_id = '$artistid'
order by trackname");
while ($row = $stmt->fetch())
{
echo '<form action="includes/attachexistingtracktoalbum.inc.php" method = "post">';
echo '<div class="checkbox">';
echo '<label>';
echo "<input type='checkbox' name='trackid[]' value='".$row['id']."' />";
echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
echo ' '.$row['trackname'];
echo '</label>';
echo "<br><label for='albumtracknum'>Track number:</label><br>
<input type='text' name='albumtracknum[]'>
<input type='hidden' name='albumid[]' value='".$albumid,"'>
<br><br>";
echo '</div>';
}
?>
<input type="hidden" name="albumidforreturn" value="<?php echo $albumid;?>">
<button type="submit" name="attachexistingtracktoalbum-submit">Attach track(s) to album</button>
<?php }
else {
header("Location: /index.php");
exit();
}?>
(注意:此处的 post 数据未针对 sql 查询进行清理,因为它已从原始相册页面以隐藏形式传递)
这会生成一个页面,其中包含当前艺术家的所有曲目名称,列表中带有复选框,每个曲目名称后面都有一个数据输入框,用于输入要添加到的专辑的曲目编号。
提交表单然后交给以下包含代码:
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "db_connect.pdo.php";
$albumid = implode(',',$_POST['albumid']);
$trackid = implode(',',$_POST['trackid']);
$albumtracknum = implode(',',$_POST['albumtracknum']);
$albumidforreturn = $_POST['albumidforreturn'];
// echo 'albumid: '.$albumid.'<br>';
// echo 'trackid: '.$trackid.'<br>';
// echo 'albumtracknum: '.$albumtracknum.'<br>';
$sql = "INSERT INTO trackconnections (albumid, trackid, albumtracknum) VALUES (?,?,?);";
$stmt= $pdo->prepare($sql);
$stmt->execute([$albumid,$trackid,$albumtracknum]);
header("Location: ../albumdetail.php?albumid=$albumidforreturn");
exit();
}
else {
header("Location: ../index.php");
exit();
}
(注意:注释掉的回声是用来测试之前表格的输出的)
我遇到的 2 个问题是我的 'Attach existing tracks to album' 表单提交:
1.传递了太多数据。
生成的表单应仅传递已勾选复选框的曲目 ID、专辑编号和曲目编号。对于插入 'trackconnections' table.
相反,它缩小了选中的复选框轨道 ID 仅,然后为每个 可用 轨道创建逗号分隔值到 select,而不仅仅是那些实际 selected.
当从表单传递数据到 include 时,这会导致烦人的输出,如下所示:
albumid: 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
trackid: 30,14
albumtracknum: ,2,3,,,,,,,,,,,,,,,,,,,,,
它应该只读作:
albumid: 4,4
trackid: 30,14
albumtracknum: 2,3
传递的数据过多意味着一旦我开始执行此操作,多个插入的行插入将不正确,因为它们不会以正确的顺序相互对齐。
2。仅包含 INSERTS 1 行到 'trackconnections' table.
看来我误解了如何使用我的代码向数据库添加多行。
因为在我的 'Attach existing tracks to album' 表单上勾选了多个复选框,每次提交表单时只会向数据库插入 1 行。
一直以来,唯一添加到 'trackconnections' table 的曲目是勾选了复选框的第一首曲目,并且由于问题编号。在上面的 1 中,albumtracknum 始终为 0,除非我在可用清单的第一个 albumtracknum 框中键入一个数字。
我需要对这段代码进行调整,以便同时解决问题 1 和 2,这意味着勾选复选框并在曲目名称后的每个框中添加曲目编号实际上会向数据库中添加多行以及它们相应的专辑曲目编号。
希望有人能帮忙
编辑以显示精炼和工作代码:
复选框和文本框部分的新代码 -
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "includes/db_connect.pdo.php";
$artistid = $_POST["artistid"];
$albumid = $_POST["albumid"];
echo '<strong>Select each track you would like to add to this album below and type in the track number you want it to have on the album in the box underneith the name of each selected track.</strong><br><br>';
$stmt = $pdo->query("SELECT * FROM track WHERE artist_id = '$artistid'
order by trackname");
echo '<form action="includes/attachexistingtracktoalbum.inc.php" method = "post">';
while ($row = $stmt->fetch())
{
echo '<div class="checkbox">';
echo '<label>';
echo "<input type='checkbox' name='trackid[]' value='".$row['id']."' />";
echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
echo ' '.$row['trackname'];
echo '</label>';
echo "<br><label for='albumtracknumber'>Track number:</label><br>
<input type='text' name='albumtracknumber_".$row['id']."'>
<input type='hidden' name='albumid[]' value='".$albumid,"'>
<br><br>";
echo '</div>';
}
?>
<input type="hidden" name="albumidforreturn" value="<?php echo $albumid;?>">
<button type="submit" name="attachexistingtracktoalbum-submit">Attach track(s) to album</button>
</form>
<?php }
else {
header("Location: /index.php");
exit();
}
包含 INSERT 处理的新代码 -
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "db_connect.pdo.php";
$albumid = implode(',',$_POST['albumid']);
$trackid = implode(',',$_POST['trackid']);
$albumidforreturn = $_POST['albumidforreturn'];
foreach($_POST['trackid'] as $trackidloop) {
$albumtracknum = $_POST["albumtracknumber_{$trackidloop}"];
$sql = "INSERT INTO trackconnections (albumid, trackid, albumtracknum) VALUES (?,?,?);";
$stmt= $pdo->prepare($sql);
$stmt->execute([$albumid,$trackidloop,$albumtracknum]);
}
header("Location: ../albumdetail.php?albumid=$albumidforreturn");
exit();
}
else {
header("Location: ../index.php");
exit();
}
这不是完整的解决方案,但我发现了一些问题:
您正在遍历曲目并为每个曲目创建一个新表格。第一个问题是,您缺少结束表单标签。我猜浏览器在看到下一个表单开始标记时会自动创建一个。 ??这就是为什么您只会得到一个 posted 复选框的原因。
我会将所有轨道复选框放入一个表单中。然后 posted trackid[] 数组将包含所有选中的项目。
[在您发表评论后进行编辑:隐藏字段 albumid[] post 整个数组,而 trackid[] 复选框仅 post 实际选中的框(HTML 规范) .
您可以将 trackID 和 albumID 放在一起作为复选框值,而不是使用 albumid[],然后在处理 post 时将它们分开解析:
$value = $row['id']. ',' . $row['albumid'];
echo "<input type='checkbox' name='trackid[]' value='".$value."' />";
此外,SQL、“INSERT INTO (..) .. VALUES (...)”仅插入一行。
SQL 对所有选中的框循环执行此操作很容易。
foreach($_POST['trackid'] as $value) {
// parse the $value...
// SQL Insert...
}
编辑 2:来自我自己的评论:
与隐藏字段一样,输入(文本)字段数组也是 post 整个数组(空白输入为空值)。 (同样,这不是 PHP 的东西,它是一个网络浏览器标准,只有 post checked 复选框和单选按钮。但是所有文本和隐藏的输入都是 posted.) 所以在你的例子中,你需要编写一个机制来知道每个复选框对应哪个文本框。快速而肮脏...您可以在复选框值中添加一个行索引 (0,1,2,3...) 作为另一个逗号分隔的数字,然后您将索引放入 posted文本框数组。或者,您可以将文本框命名为 ' .. name="textinput_' . $row['trackid'] . '" ...'
(不是数组),然后在 post 上使用
在 foreach 循环中读取它们
$val = $_POST["textinput_{$trackid}"];
我正在为音乐数据库编写唱片工具。
艺术家能够将曲目、单曲、EP 和专辑全部插入数据库中单独的 table。
将曲目分开 table 允许将相同的曲目附加到多首单曲、EP 和专辑中,而只需要在数据库中为该曲目提供一条记录。
这意味着单个曲目页面可以有一个自动生成的链接列表,返回到它们出现的单曲、EP 和专辑。使通过网站浏览数据库的体验更加顺畅。
我已经到了我正在编写一个工具的地步,可以将数据库中给定艺术家的任何现有曲目附加到专辑页面上。
我正在数据库中使用另一个名为 'trackconnections' 的 table 来创建曲目 table 中的曲目 ID 和专辑 [=98 中的专辑 ID 之间的关系链接=],还有一个名为 albumtracknum 的附加列,可以在专辑页面上查询时以正确的顺序输出曲目。
该工具的代码位于标记为 'Attach existing track(s) to album' 的按钮后面。该工具的代码如下:
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "includes/db_connect.pdo.php";
$artistid = $_POST["artistid"];
$albumid = $_POST["albumid"];
echo '<strong>Select each track you would like to add to this album below and type in the track number you want it to have on the album in the box underneith the name of each selected track.</strong><br><br>';
$stmt = $pdo->query("SELECT * FROM track WHERE artist_id = '$artistid'
order by trackname");
while ($row = $stmt->fetch())
{
echo '<form action="includes/attachexistingtracktoalbum.inc.php" method = "post">';
echo '<div class="checkbox">';
echo '<label>';
echo "<input type='checkbox' name='trackid[]' value='".$row['id']."' />";
echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
echo ' '.$row['trackname'];
echo '</label>';
echo "<br><label for='albumtracknum'>Track number:</label><br>
<input type='text' name='albumtracknum[]'>
<input type='hidden' name='albumid[]' value='".$albumid,"'>
<br><br>";
echo '</div>';
}
?>
<input type="hidden" name="albumidforreturn" value="<?php echo $albumid;?>">
<button type="submit" name="attachexistingtracktoalbum-submit">Attach track(s) to album</button>
<?php }
else {
header("Location: /index.php");
exit();
}?>
(注意:此处的 post 数据未针对 sql 查询进行清理,因为它已从原始相册页面以隐藏形式传递)
这会生成一个页面,其中包含当前艺术家的所有曲目名称,列表中带有复选框,每个曲目名称后面都有一个数据输入框,用于输入要添加到的专辑的曲目编号。
提交表单然后交给以下包含代码:
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "db_connect.pdo.php";
$albumid = implode(',',$_POST['albumid']);
$trackid = implode(',',$_POST['trackid']);
$albumtracknum = implode(',',$_POST['albumtracknum']);
$albumidforreturn = $_POST['albumidforreturn'];
// echo 'albumid: '.$albumid.'<br>';
// echo 'trackid: '.$trackid.'<br>';
// echo 'albumtracknum: '.$albumtracknum.'<br>';
$sql = "INSERT INTO trackconnections (albumid, trackid, albumtracknum) VALUES (?,?,?);";
$stmt= $pdo->prepare($sql);
$stmt->execute([$albumid,$trackid,$albumtracknum]);
header("Location: ../albumdetail.php?albumid=$albumidforreturn");
exit();
}
else {
header("Location: ../index.php");
exit();
}
(注意:注释掉的回声是用来测试之前表格的输出的)
我遇到的 2 个问题是我的 'Attach existing tracks to album' 表单提交:
1.传递了太多数据。
生成的表单应仅传递已勾选复选框的曲目 ID、专辑编号和曲目编号。对于插入 'trackconnections' table.
相反,它缩小了选中的复选框轨道 ID 仅,然后为每个 可用 轨道创建逗号分隔值到 select,而不仅仅是那些实际 selected.
当从表单传递数据到 include 时,这会导致烦人的输出,如下所示:
albumid: 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
trackid: 30,14
albumtracknum: ,2,3,,,,,,,,,,,,,,,,,,,,,
它应该只读作:
albumid: 4,4
trackid: 30,14
albumtracknum: 2,3
传递的数据过多意味着一旦我开始执行此操作,多个插入的行插入将不正确,因为它们不会以正确的顺序相互对齐。
2。仅包含 INSERTS 1 行到 'trackconnections' table.
看来我误解了如何使用我的代码向数据库添加多行。
因为在我的 'Attach existing tracks to album' 表单上勾选了多个复选框,每次提交表单时只会向数据库插入 1 行。
一直以来,唯一添加到 'trackconnections' table 的曲目是勾选了复选框的第一首曲目,并且由于问题编号。在上面的 1 中,albumtracknum 始终为 0,除非我在可用清单的第一个 albumtracknum 框中键入一个数字。
我需要对这段代码进行调整,以便同时解决问题 1 和 2,这意味着勾选复选框并在曲目名称后的每个框中添加曲目编号实际上会向数据库中添加多行以及它们相应的专辑曲目编号。
希望有人能帮忙
编辑以显示精炼和工作代码:
复选框和文本框部分的新代码 -
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "includes/db_connect.pdo.php";
$artistid = $_POST["artistid"];
$albumid = $_POST["albumid"];
echo '<strong>Select each track you would like to add to this album below and type in the track number you want it to have on the album in the box underneith the name of each selected track.</strong><br><br>';
$stmt = $pdo->query("SELECT * FROM track WHERE artist_id = '$artistid'
order by trackname");
echo '<form action="includes/attachexistingtracktoalbum.inc.php" method = "post">';
while ($row = $stmt->fetch())
{
echo '<div class="checkbox">';
echo '<label>';
echo "<input type='checkbox' name='trackid[]' value='".$row['id']."' />";
echo '<span class="cr"><i class="cr-icon glyphicon glyphicon-ok"></i></span>';
echo ' '.$row['trackname'];
echo '</label>';
echo "<br><label for='albumtracknumber'>Track number:</label><br>
<input type='text' name='albumtracknumber_".$row['id']."'>
<input type='hidden' name='albumid[]' value='".$albumid,"'>
<br><br>";
echo '</div>';
}
?>
<input type="hidden" name="albumidforreturn" value="<?php echo $albumid;?>">
<button type="submit" name="attachexistingtracktoalbum-submit">Attach track(s) to album</button>
</form>
<?php }
else {
header("Location: /index.php");
exit();
}
包含 INSERT 处理的新代码 -
if (isset($_POST['attachexistingtracktoalbum-submit'])) {
require "db_connect.pdo.php";
$albumid = implode(',',$_POST['albumid']);
$trackid = implode(',',$_POST['trackid']);
$albumidforreturn = $_POST['albumidforreturn'];
foreach($_POST['trackid'] as $trackidloop) {
$albumtracknum = $_POST["albumtracknumber_{$trackidloop}"];
$sql = "INSERT INTO trackconnections (albumid, trackid, albumtracknum) VALUES (?,?,?);";
$stmt= $pdo->prepare($sql);
$stmt->execute([$albumid,$trackidloop,$albumtracknum]);
}
header("Location: ../albumdetail.php?albumid=$albumidforreturn");
exit();
}
else {
header("Location: ../index.php");
exit();
}
这不是完整的解决方案,但我发现了一些问题: 您正在遍历曲目并为每个曲目创建一个新表格。第一个问题是,您缺少结束表单标签。我猜浏览器在看到下一个表单开始标记时会自动创建一个。 ??这就是为什么您只会得到一个 posted 复选框的原因。 我会将所有轨道复选框放入一个表单中。然后 posted trackid[] 数组将包含所有选中的项目。
[在您发表评论后进行编辑:隐藏字段 albumid[] post 整个数组,而 trackid[] 复选框仅 post 实际选中的框(HTML 规范) .
您可以将 trackID 和 albumID 放在一起作为复选框值,而不是使用 albumid[],然后在处理 post 时将它们分开解析:
$value = $row['id']. ',' . $row['albumid'];
echo "<input type='checkbox' name='trackid[]' value='".$value."' />";
此外,SQL、“INSERT INTO (..) .. VALUES (...)”仅插入一行。
SQL 对所有选中的框循环执行此操作很容易。
foreach($_POST['trackid'] as $value) {
// parse the $value...
// SQL Insert...
}
编辑 2:来自我自己的评论:
与隐藏字段一样,输入(文本)字段数组也是 post 整个数组(空白输入为空值)。 (同样,这不是 PHP 的东西,它是一个网络浏览器标准,只有 post checked 复选框和单选按钮。但是所有文本和隐藏的输入都是 posted.) 所以在你的例子中,你需要编写一个机制来知道每个复选框对应哪个文本框。快速而肮脏...您可以在复选框值中添加一个行索引 (0,1,2,3...) 作为另一个逗号分隔的数字,然后您将索引放入 posted文本框数组。或者,您可以将文本框命名为 ' .. name="textinput_' . $row['trackid'] . '" ...'
(不是数组),然后在 post 上使用
在 foreach 循环中读取它们
$val = $_POST["textinput_{$trackid}"];