Foreach 通过 2 个数组只循环第一个元素
Foreach through 2 arrays only loops the first element
我根据表单输入创建了 2 个不同的数组 $postvalues
和 $filut
。然后,我在单击按钮时将数组发送到我的数据库 table。数组由文件名和一个小介绍组成。
for($i=0; $i<count($_FILES['upload']['name']); $i++)
{
$filut = basename($_FILES['upload']['name'][$i]);
}
if(isset($_POST['subi']))
{
$data1 = $_POST['answers'];
foreach($data1) as $postValues)
{
$sql4 = 'INSERT INTO db_image (text, image) VALUES("'.$postValues.'","'.$filut.'")';
$my->query($sql4);
}
}
这里的问题是输出。 foreach 循环输出 $postValues
正确但只复制 $filut
第一个元素。
错误输出示例:
this is picture1 picture1.png
this is picture2 picture1.png //Supposed to say 2nd element of $filut: "picture2.png"
Foreach 正确地遍历第一个数组,但只复制 $filut
数组。我尝试寻找答案并尝试组合数组但没有成功。
如何正确循环遍历两个数组并将它们插入数据库?
您的数据库查询不安全,因为它将原始 POST 数据直接发送到数据库。验证您的输入,并改用准备好的语句。
您的错误在这里:
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
$filut = basename($_FILES['upload']['name'][$i]);
}
$filut 正在重新分配给 $_FILES 的最后一个元素。因此只持有一个值。 $filut 应该是一个数组吗?
试试这个:
$filut = array();
for($i=0; $i<count($_FILES['upload']['name']); $i++)
{
$filut[$i] = basename($_FILES['upload']['name'][$i]);
}
$i = 0; //Reset
if(isset($_POST['subi']))
{
$data1 = $_POST['answers'];
foreach($data1 as $postValues)
{
$sql4 = 'INSERT INTO db_image (text, image) VALUES("'.$postValues.'","'.$filut[$i].'")';
$my->query($sql4);
$i++ //Increment
}
}
这听起来像是您在尝试使用嵌套循环,但实际上您在开始时有一个循环关闭,然后循环遍历其余部分。您需要移动下面标记的右花括号:
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
$filut = basename($_FILES['upload']['name'][$i]);
} <<<<<<<<<=========== This curly brace closes the "for loop"
if(isset($_POST['subi'])) {
$data1 = $_POST['answers'];
foreach($data1) as $postValues) {
$sql4 = 'INSERT INTO db_image (text, image) VALUES("'.$postValues.'","'.$filut.'")';
$my->query($sql4);
}
}
??? <<<<<======== For a nested loop you should close it here
或者您尝试将 $filut
分配为数组,在这种情况下,起始 for...
循环需要如下所示:
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
$filut[] = basename($_FILES['upload']['name'][$i]);
}
(注意在$filut
后加[]
。)
但是,如果这是您想要的(将 $filut 放入一个数组),那么您需要在下面做一些不同的事情,以便仅访问数组的一个元素。这是嵌套的 foreach
可以解决问题的地方 - 也许这就是您打算完成它的方式:
if(isset($_POST['subi'])) {
$data1 = $_POST['answers'];
foreach($data1 as $postValues) {
foreach ($filut as $f) {
$sql4 = 'INSERT INTO db_image (text, image)
VALUES("'.$postValues.'","'.$f.'")';
$my->query($sql4);
}
}
}
这将为 $_POST['answers'] 中的每个值的 $filut 中的每个值插入一行。那是你想要的吗?还是 $filut 和 $_POST['answers'] 是并行的,并且您希望在插入时有 1-1 的相关性?
最后,我建议您使用 prepare 和 bind,因为您是从用户那里获取数据的。这个例子 copied/modified 来自 here:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* Prepare an insert statement */
$query = "INSERT INTO db_image (text, image) VALUES (?,?)";
$stmt = $my->prepare($query);
#### NOTE THE USE OF YOUR VARIABLES HERE IN THE BIND - the "ss" means they are strings
$stmt->bind_param("ss", $postValues, $f);
#### HERE IS WHERE YOUR CODE IS GETTING INSERTED
foreach($data1 as $postValues) {
foreach ($filut as $f) {
/* Execute the statement */
$stmt->execute();
}
}
/* close statement */
$stmt->close();
/* close connection */
$my->close();
?>
我不能保证我更改了所有变量以匹配您的代码,但希望它足够接近以给您一个想法。此解决方案 (1) 保护您免受 SQL 注入(否则这是您代码中的一个严重缺陷)并且 (2) 通过 prepare/execute 循环会更快。
请注意我示例中的仔细缩进,其中所有内容都完美对齐,每个缩进有 3 个或更多空格 - 我无法告诉你有多少次我看到草率(或太少)的缩进使人们错过本来很明显的问题。
假设上传的文件数量等于 $data 数组的长度,我会尝试这样做:
$data1 = $_POST['answers'];
for($i=0; $i<length($data); $i++){
$filut = basename($_FILES['upload']['name'][$i]);
if(isset($_POST['subi'])) {
$postValue = $data[$i];
$sql4 = 'INSERT INTO db_image (text, image) VALUES("'.$postValues.'","'.$filut.'")';
$my->query($sql4);
}
}
我根据表单输入创建了 2 个不同的数组 $postvalues
和 $filut
。然后,我在单击按钮时将数组发送到我的数据库 table。数组由文件名和一个小介绍组成。
for($i=0; $i<count($_FILES['upload']['name']); $i++)
{
$filut = basename($_FILES['upload']['name'][$i]);
}
if(isset($_POST['subi']))
{
$data1 = $_POST['answers'];
foreach($data1) as $postValues)
{
$sql4 = 'INSERT INTO db_image (text, image) VALUES("'.$postValues.'","'.$filut.'")';
$my->query($sql4);
}
}
这里的问题是输出。 foreach 循环输出 $postValues
正确但只复制 $filut
第一个元素。
错误输出示例:
this is picture1 picture1.png
this is picture2 picture1.png //Supposed to say 2nd element of $filut: "picture2.png"
Foreach 正确地遍历第一个数组,但只复制 $filut
数组。我尝试寻找答案并尝试组合数组但没有成功。
如何正确循环遍历两个数组并将它们插入数据库?
您的数据库查询不安全,因为它将原始 POST 数据直接发送到数据库。验证您的输入,并改用准备好的语句。
您的错误在这里:
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
$filut = basename($_FILES['upload']['name'][$i]);
}
$filut 正在重新分配给 $_FILES 的最后一个元素。因此只持有一个值。 $filut 应该是一个数组吗?
试试这个:
$filut = array();
for($i=0; $i<count($_FILES['upload']['name']); $i++)
{
$filut[$i] = basename($_FILES['upload']['name'][$i]);
}
$i = 0; //Reset
if(isset($_POST['subi']))
{
$data1 = $_POST['answers'];
foreach($data1 as $postValues)
{
$sql4 = 'INSERT INTO db_image (text, image) VALUES("'.$postValues.'","'.$filut[$i].'")';
$my->query($sql4);
$i++ //Increment
}
}
这听起来像是您在尝试使用嵌套循环,但实际上您在开始时有一个循环关闭,然后循环遍历其余部分。您需要移动下面标记的右花括号:
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
$filut = basename($_FILES['upload']['name'][$i]);
} <<<<<<<<<=========== This curly brace closes the "for loop"
if(isset($_POST['subi'])) {
$data1 = $_POST['answers'];
foreach($data1) as $postValues) {
$sql4 = 'INSERT INTO db_image (text, image) VALUES("'.$postValues.'","'.$filut.'")';
$my->query($sql4);
}
}
??? <<<<<======== For a nested loop you should close it here
或者您尝试将 $filut
分配为数组,在这种情况下,起始 for...
循环需要如下所示:
for($i=0; $i<count($_FILES['upload']['name']); $i++) {
$filut[] = basename($_FILES['upload']['name'][$i]);
}
(注意在$filut
后加[]
。)
但是,如果这是您想要的(将 $filut 放入一个数组),那么您需要在下面做一些不同的事情,以便仅访问数组的一个元素。这是嵌套的 foreach
可以解决问题的地方 - 也许这就是您打算完成它的方式:
if(isset($_POST['subi'])) {
$data1 = $_POST['answers'];
foreach($data1 as $postValues) {
foreach ($filut as $f) {
$sql4 = 'INSERT INTO db_image (text, image)
VALUES("'.$postValues.'","'.$f.'")';
$my->query($sql4);
}
}
}
这将为 $_POST['answers'] 中的每个值的 $filut 中的每个值插入一行。那是你想要的吗?还是 $filut 和 $_POST['answers'] 是并行的,并且您希望在插入时有 1-1 的相关性?
最后,我建议您使用 prepare 和 bind,因为您是从用户那里获取数据的。这个例子 copied/modified 来自 here:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* Prepare an insert statement */
$query = "INSERT INTO db_image (text, image) VALUES (?,?)";
$stmt = $my->prepare($query);
#### NOTE THE USE OF YOUR VARIABLES HERE IN THE BIND - the "ss" means they are strings
$stmt->bind_param("ss", $postValues, $f);
#### HERE IS WHERE YOUR CODE IS GETTING INSERTED
foreach($data1 as $postValues) {
foreach ($filut as $f) {
/* Execute the statement */
$stmt->execute();
}
}
/* close statement */
$stmt->close();
/* close connection */
$my->close();
?>
我不能保证我更改了所有变量以匹配您的代码,但希望它足够接近以给您一个想法。此解决方案 (1) 保护您免受 SQL 注入(否则这是您代码中的一个严重缺陷)并且 (2) 通过 prepare/execute 循环会更快。
请注意我示例中的仔细缩进,其中所有内容都完美对齐,每个缩进有 3 个或更多空格 - 我无法告诉你有多少次我看到草率(或太少)的缩进使人们错过本来很明显的问题。
假设上传的文件数量等于 $data 数组的长度,我会尝试这样做:
$data1 = $_POST['answers'];
for($i=0; $i<length($data); $i++){
$filut = basename($_FILES['upload']['name'][$i]);
if(isset($_POST['subi'])) {
$postValue = $data[$i];
$sql4 = 'INSERT INTO db_image (text, image) VALUES("'.$postValues.'","'.$filut.'")';
$my->query($sql4);
}
}