【问题标题】:Foreach inside of While Loop Looks FunnyWhile 循环中的 Foreach 看起来很有趣
【发布时间】:2012-05-01 17:06:13
【问题描述】:

运行后我不断得到一个奇怪的列表:

<?php 
  $query_Category = "SELECT * FROM blog_categories ORDER BY category ASC";

  $getCategory = mysql_query($query_Category) or die(mysql_error()); 
?>

<div id="sheader" style="">Categories</div>

<div class="sbody" style="color:#000 !important;">

<?php 
   do { 
?>
    <div><?php echo $row_getCategory['category'];?></div>

<?php 
    $cat = $row_getCategory['cat_id'];

    $query_Subcategory = "SELECT * FROM blog_subcategories WHERE primcat_id = '$cat' ORDER BY subcategory ASC";

    $getSubCategory = mysql_query($query_Subcategory) or die(mysql_error());
    $row_getSubCategory = mysql_fetch_assoc($getSubCategory);

    $str = $row_getSubCategory['subcategory']; $subcategory = explode(',', $str);

    foreach ($subcategory as $arraysubcat) 
    {
       echo '<div>' . $arraysubcat . '</div>';
    }
    } while ($row_getCategory = mysql_fetch_assoc($getCategory)); 
?>

</div>
<?php mysql_free_result($getCategory); ?>

我有一个包含 id 和类别的类别表和一个包含 id、子类别和主要类别 ID 的子类别表。 我运行它,它首先随机显示 foreach。

【问题讨论】:

  • 我只是觉得你的代码格式看起来很有趣。 O.o $subcategory 数组是否按照您对 explode() 的期望输出?
  • @Blake 我来这里是期待一个 PHP 语法讨厌的节日。
  • 我为您修正了代码格式。在我看来它仍然很有趣,但这就是beta.phpformatter.com 所说的样子。
  • 您查询类别但不对其执行任何操作,然后查询子类别并打印出一行的爆炸,然后您从类别中获取行并且不执行任何操作。那是你的意图吗?因为根据您的代码,即使这样也行不通。 $cat 变量正在从未定义的数组 $row_getCategory 中获取其值。哦,等等......你正在定义它......在你的代码末尾......好吧......你明白了我,我完全迷路了
  • 像进入/退出php模式那样拆分语句会让人难以阅读。

标签: php loops foreach while-loop


【解决方案1】:

你的代码让我很头疼,但我相信你的问题就在这里:

$cat = $row_getCategory['cat_id'];

$row_getCategory 是在您的代码末尾获取的,因此该代码无法正常工作。

我相信你想做这样的事情

while ($row_getCategory = mysql_fetch_assoc($getCategory))
{
    $cat = $row_getCategory['cat_id'];

    $query_Subcategory = "SELECT * FROM blog_subcategories WHERE primcat_id = '$cat' ORDER BY subcategory ASC";

    $getSubCategory = mysql_query($query_Subcategory) or die(mysql_error());
    $row_getSubCategory = mysql_fetch_assoc($getSubCategory);

    $str         = $row_getSubCategory['subcategory'];
    $subcategory = explode(',', $str);

    foreach ($subcategory as $arraysubcat) {
        echo '<div>' . $arraysubcat . '</div>';
    }

    }

}

【讨论】:

    【解决方案2】:

    您不需要为每个类别执行单独的子查询。就做个join吧。试试这个:

    $db = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
    
    if ($mysqli->connect_error) {
        die('Connect Error (' . $mysqli->connect_errno . ') '
                . $mysqli->connect_error);
    }
    
    $get_categories = $db -> query("SELECT category, subcategory 
                        FROM blog_categories, blog_subcategories
                        WHERE primcat_id = cat_id
                        ORDER BY category ASC, subcategory ASC");
    
    echo "<h1>Categories</h1>";
    
    echo "<ul>";
    
    while($row = $get_categories -> fetch_assoc()) {
        echo "<li>" . $row['category'];
        if($row['subcategory']) {
            echo "<ul>";
            foreach(explode(",",$row['subcategory']) as $subcategory ) {
                echo "<li>$subcategory</li>";
            }
            echo "</ul>";
        }
        echo "</li>";
    }
    
    echo "</ul>";
    

    【讨论】:

    • Awww...我刚刚完成了几乎相同的代码(语义上)与组合查询和嵌套 UL 的编写。恩,不用再发了。 ^_~ 干得好!
    【解决方案3】:

    有时可以在while 中包含foreach,但这不是其中之一。首先,您正在执行do ... while 循环,这意味着无论是否找到行,您都将逐步执行所有代码,因此如果数据库中不存在行,您可能会收到undefined index 错误。其次,您正在为外部 while 循环的每次迭代执行子类别查询,这意味着如果您的查询返回 100 行,那么您将发出 100 个查询,这不好。

    最好的办法是在两个表之间创建一个连接,并在一个循环中逐步遍历行,最好是一个 while 循环(而不是 do ... while 循环)。

    类似这样的:

    // Made some assumptions with the query, as no schema was posted
    // But should give you a starting point
    $sql = 
    'SELECT bc.*, GROUP_CONCAT(bsc.subcategory) AS sub_categories ' .
    'FROM blog_categories AS BC INNER JOIN blog_subcategories AS bsc ON bsc.primcat_id = bc.id ' .
    'GROUP BY bc.id ' .
    'ORDER BY bc.category ASC';
    

    现在您只有一个查询来检索所有类别及其关联的子类别,现在您可以使用单个 while 循环逐步完成它们:

    $query = mysql_query($sql) or die(mysql_error());
    
    while ($row = mysql_fetch_assoc($query)) {
    
        <div>
          <?php echo $row['category']; ?>
        </div>
    
        // To get at subcategories you can do this
        $subCategories = array_map('trim', explode(',', $row['sub_categories']));
    
        // And sort them ASC
        sort($subCategories);
    
        foreach ($subCategories as $subCategory) {
            echo '<div>' . $subCategory . '</div>';
        }
    }
    

    【讨论】:

      【解决方案4】:

      我认为您不应该使用do while 从数据库中检索数据。您应该使用while 循环,因为do while 在检查条件之前运行循环一次。所以在第一个循环中,您将在echo $row_getCategory['category']; 变量中没有得到任何数据。所以请尝试使用以下代码:

      <?php
      while ($row_getCategory = mysql_fetch_assoc($getCategory)){
      ?>
              <div>
                <?php
                  echo $row_getCategory['category'];      
                 ?>
              </div>
              <?php
                  $cat = $row_getCategory['cat_id'];
      
                  $query_Subcategory = "SELECT * FROM blog_subcategories WHERE primcat_id = '$cat' ORDER BY subcategory ASC";
      
                  $getSubCategory = mysql_query($query_Subcategory) or die(mysql_error());
                  $row_getSubCategory = mysql_fetch_assoc($getSubCategory);
      
                  $str         = $row_getSubCategory['subcategory'];
                  $subcategory = explode(',', $str);
      
                  foreach ($subcategory as $arraysubcat) {
                      echo '<div>' . $arraysubcat . '</div>';
                  }
              ?>
      <?php
      } 
      ?>
      

      【讨论】:

      • 感谢工作就像一个魅力> 我会努力在格式方面做得更好。
      猜你喜欢
      • 2013-06-24
      • 1970-01-01
      • 2011-08-06
      • 2013-10-01
      • 2015-06-16
      • 1970-01-01
      • 2023-04-09
      • 2017-05-28
      • 2013-06-27
      相关资源
      最近更新 更多