带有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

从这个表中,我根据表productgroup_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 表有名为 idquote_idprod_idrep_idqty 的列

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语句的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌套 if/else 语句的 While 循环

PHP - If/else, for, foreach, while - 没有花括号?

在if语句中有两个foreach循环

Foreach带有if(空)语句

初学python随笔——控制和循环语句

java 流程控制基础之if else