带有if和else语句的foreach循环在if语句为假时不执行else语句
Posted
技术标签:
【中文标题】带有if和else语句的foreach循环在if语句为假时不执行else语句【英文标题】:Foreach loop with if and else statement does not execute the else statement when the if statement is false 【发布时间】:2020-03-20 15:01:25 【问题描述】:背景:
我有一个关于各种产品的数据库表。此数据库表称为产品。列设置为id | group_id | model | description | price |
。
id = the product id.
group_id = identifies the group that this product belongs too.
model = product model
description = Description
price = Price
从这个表中,我根据表product
的group_id
生成一个动态表。
<table>
<tr>
<th>Model</th>
<th>Description</th>
<th>Price</th>
<th>QTY</th>
</tr>
<?php
$conn = mysqli_connect("localhost", "root", "root", "test");
// Check connection
if ($conn->connect_error)
die("Connection failed: " . $conn->connect_error);
$sql ="SELECT * FROM product WHERE group_id = 2";
$result = $conn->query($sql);
while($row = $result->fetch_assoc()) :
?>
<tr>
<td><?php echo $row['model']; ?></td>
<td><?php echo $row['description']; ?></td>
<td>R <?php echo $row['price']; ?></td>
<td><input type="number" name = "<?php echo $row['id']?>" value = 0></td>
</tr>
<?php endwhile; ?>
</table>
<div class="input-group">
<button type="submit" class="btn" name="save">Save and Return</button>
</div>
</form>
这很好用。生成此表后,它允许用户编辑属于该group id
的每个产品的quantity
,使用POST
提交后,信息将发送到config_824.php
请参阅下面的代码以获取此文件。
<?php
session_start();
include ('customer_details_config.php');
$quote_id = $_SESSION['quote_id'];
$salesman_id = $_SESSION['salesman_id'];
$db = mysqli_connect('localhost', 'root', 'root', 'test');
if (isset($_POST['save_pan_han']))
unset($_POST['save_pan_han']);
foreach($_POST as $key => $value):
$test_query = "SELECT * FROM quote_items WHERE quote_id = $quote_id AND prod_id = $key AND rep_id = $salesman_id";
$result = mysqli_query($db, $test_query);
$item = mysqli_fetch_assoc($result) or die (mysqli_error($db));
if($item['quote_id'] == $quote_id &&
$item['prod_id'] == $key &&
$item['rep_id'] == $salesman_id)
$update_query = "UPDATE quote_items SET
qty = $value
WHERE
quote_id = $quote_id
AND prod_id = $key
AND rep_id = $salesman_id
";
mysqli_query($db,$update_query) or die (mysqli_error($db));
else
$query = "INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) VALUES ($quote_id, $key, $salesman_id, $value)" ;
mysqli_query($db,$query) or die (mysqli_error($db));
endforeach;
?>
$quote_id
设置为$_SESSION['quote_id']
,$salesman_id
在用户登录时设置为$_SESSION['salesman_id']
。
quote items 表有名为 id
、quote_id
、prod_id
、rep_id
、qty
的列
CREATE TABLE `project`.`quote_items` ( `id` INT(10) NOT NULL AUTO_INCREMENT , `quote_id` INT(10) NOT NULL , `prod_id` INT(10) NOT NULL , `rep_id` INT(10) NOT NULL , `qty` INT(10) NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;
根据上面的代码,我正在尝试将数据插入到名为 quote_items 的数据库表中,如果我将测试数据插入到数据库中,UPDATE
查询运行良好。
问题:
问题是,如果它检查并且该行不在数据库中,则INSERT
查询不起作用。尽管error showing = TRUE
,我也没有看到任何错误。
我将使用以下示例:
我在数据库中有六行测试数据。动态表允许设置 8 个值并将其发送到数据库。所以说前两个值已经在数据库中并且符合UPDATE
查询。值 3 和 4 尚未插入,将属于 INSERT
查询。值 5、6、7 和 8 再次属于 Update
查询。
如果我运行代码。只有第 1 行和第 2 行会被更新。不会插入第 3 行和第 4 行,也不会更新第 5、6、7、8 行。
我尝试过的:
*** using mysqli_autocommit($db,FALSE);
复制查询并通过phpMyAdmin
中的SQL
插入数据库,如果我从查询中删除变量,它在INSERT
上工作正常。
正如您在上面的代码中看到的,当我回显包含表name
的数组时,我注意到我有一个unset($var)。这是一个字符串。如果我尝试插入一个字符串,这显然会导致问题,我认为这会解决问题。
遗憾的是,事实并非如此。
通过删除 if 和 elseif 并仅使用下面评论中推荐的 insert 进行测试:
<?php
include ('customer_details_config.php');
$quote_id = $_SESSION['quote_id'];
$salesman_id = $_SESSION['salesman_id'];
$db = mysqli_connect('localhost', 'root', 'root', 'test');
if (isset($_POST['save_pan_han'])):
foreach($_POST as $key => $value):
$test_query = "INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) VALUES ($quote_id, $key, $salesman_id, $value)";
$result = mysqli_query($db, $test_query) or die (mysqli_error($db));
/*
$item = mysqli_fetch_assoc($result) ;
if ($item['quote_id'] == $quote_id &&
$item['prod_id'] == $key &&
$item['rep_id'] == $salesman_id
)
$update_query = "UPDATE quote_items SET
qty = $value
WHERE
quote_id = $quote_id
AND prod_id = $key
AND rep_id = $salesman_id
";
mysqli_query($db,$update_query) or die (mysqli_error($db));
else
$query = "INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) VALUES ($quote_id, $key, $salesman_id, $value)" ;
mysqli_query($db,$query) or die (mysqli_error($db));
*/
endforeach;
endif;
?>
【问题讨论】:
【参考方案1】:您在插入时向列名添加 '' 是否有原因? 当您执行更新时,您不会这样做。
替换这个:
"INSERT INTO quote_items ('quote_id', 'prod_id', 'rep_id', 'qty') VALUES ($quote_id, $key, $salesman_id, $value)"
与:
"INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) VALUES ($quote_id, $key, $salesman_id, $value)"
或者也许你想使用这个:`
"INSERT INTO quote_items (`quote_id`, `prod_id`, `rep_id`, `qty`) VALUES ($quote_id, $key, $salesman_id, $value)"
查看DEMO
【讨论】:
谢谢,我已经相应地编辑了我的代码以及在这篇文章中。我可以确认这并没有解决问题。但我理解你为什么提出这个建议。但是,我也查看了演示,但没有遇到与您相同的错误。如果我至少有错误会有所帮助。 我明白了。请注意,您可以“投票”所有有用的答案,然后最后您可以接受对您帮助最大的答案,或者换句话说,它是正确的答案。 @WWessels 请你解释一下这什么时候会是真的:$item['quote_id'] != $quote_id && $item['prod_id'] != $key && $item['rep_id' ] != $salesman_id 通过更新查询,我使用条件来测试表中匹配的行是否存在,如果存在,则应该更新该行。使用插入查询,我测试以确认如果该行不存在,则不应插入该行。所以简而言之,确保没有行 WHERE quote_id IS NOT $quote_id AND prod_id IS NOT $key AND rep_id IS NOT $salesman_id,如果 TRUE 然后插入新行。这有什么帮助吗... 我什至已经删除了 elseif 并使其成为 else,取出 else if 的条件以及当 if 不是 TRUE 插入数据库时,这也不起作用。 【参考方案2】:像在更新语句中所做的那样,在插入语句中的值周围添加单引号,以便它们在 SQL 中被正确识别为字符串。
当然,除了不是字符串的字段,但由于您没有发布您的创建表脚本,因此无法从您的代码中分辨出来。
同样使用字符串连接来构建 SQL 语句是一个可怕的安全问题,你绝对必须使用 PDO 和准备好的语句!
【讨论】:
感谢您的帮助。我已经为您添加了缺少的代码。我还添加了单引号,并再次测试。这些值是整数,数据库中的字段类型也是如此,所以这应该不是问题。我同意准备好的陈述的重要性,这只是一个正在构建的测试原型,还没有打算投入使用。如果我对项目有足够的兴趣,我会查看验证和准备好的声明。【参考方案3】:我终于得到了我想要的结果。差不多吧。
$db = mysqli_connect('localhost', 'root', 'root', 'test');
if (isset($_POST['save_pan_han']))
unset($_POST['save_pan_han']);
foreach($_POST as $key => $value):
$query = "INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) SELECT $quote_id, $key, $salesman_id, $value WHERE NOT EXISTS (SELECT quote_id, prod_id, rep_id, qty FROM quote_items WHERE quote_id = $quote_id AND prod_id = $key AND rep_id = $salesman_id)";
mysqli_query($db,$query) or die (mysqli_error($db));
endforeach;
foreach($_POST as $key => $value):
$test_query = "SELECT * FROM quote_items WHERE quote_id = $quote_id AND prod_id = $key AND rep_id = $salesman_id";
$result = mysqli_query($db, $test_query);
$item = mysqli_fetch_assoc($result) or die (mysqli_error($db));
if($item['quote_id'] == $quote_id &&
$item['prod_id'] == $key &&
$item['rep_id'] == $salesman_id)
$update_query = "UPDATE quote_items SET
qty = $value
WHERE
quote_id = $quote_id
AND prod_id = $key
AND rep_id = $salesman_id
";
mysqli_query($db,$update_query) or die (mysqli_error($db));
endforeach;
?>
唯一的问题是现在这也会在qty = 0
处插入行
我将只包含一个DROP
查询。如果有人有更好的建议,请补充。我知道我对数据库进行了太多调用,这不是最佳解决方案。
【讨论】:
警告:您对SQL Injections 持开放态度,应该使用参数化的prepared statements,而不是手动构建查询。它们由PDO 或MySQLi 提供。永远不要相信任何形式的输入!即使您的查询仅由受信任的用户执行,you are still in risk of corrupting your data。 Escaping is not enough!以上是关于带有if和else语句的foreach循环在if语句为假时不执行else语句的主要内容,如果未能解决你的问题,请参考以下文章