You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP while循环内嵌套foreach返回重复行问题排查

嵌套复选框列表重复输出问题排查与修复

我正在尝试用PHP创建一个嵌套复选框列表,编写了while循环内嵌套多层foreach循环的代码。目前输出结果大致符合预期,但存在第一个foreach循环的内容随循环次数增加而重复的问题(比如第一个主复选框显示1次,第二个显示2次,第三个显示3次),请问代码中哪里出现了问题?

<?php
     $sql_concern="SELECT * FROM sister_concern  where Base_user='$User_id' And Status='Active'";
     $result_concern = mysqli_query($link,$sql_concern);
                                  
     if(mysqli_num_rows($result_concern) > 0){
         echo '<ul>';
         while($row = mysqli_fetch_array($result_concern)){
         $sisid=$row['Id'];
         $name=$row['Name'];
         $namearray[]=$name;

             foreach($namearray as $data){
             
             echo '<li style="list-style-type:none;"><input type="checkbox" name="sister_concern" class="chkMainConcern" id="chkMainConcern'.$sisid.'" value="'.$sisid.'" > '.$name.' </li>';
                                                 
             //fetch module Name for each concern
             $sql_module="SELECT * FROM Module where Status='Active'";
             $result_module = mysqli_query($link,$sql_module);
                 
                //this one coming duplicate                                
                 echo '<ul class="modulename'.$sisid.'" style="display:none;">';
                 while($rowmodule = mysqli_fetch_array($result_module)){
                 $modid=$rowmodule['Id'];
                 $modname=$rowmodule['Name'];
                 $modearray[]=$modname;

                      foreach($modearray as $val){
                         //module name 
                         echo '<li style="list-style-type:none;"><input type="checkbox" value="'.$modid.'"> '.$rowmodule['Name'].' </li>'; 
                                                        
                          //fetch module permission for each module
                          $sql_modhooks="SELECT * FROM Module_hooks where Status='Active' and ModuleID='$modid'";
                          $result_modhooks = mysqli_query($link,$sql_modhooks);
                          echo '<ul class="modulehooks'.$modid.'" style="display:none;">';
                          while($row_modhooks = mysqli_fetch_array($result_modhooks)){
                             echo '<li style="list-style-type:none;"><input type="checkbox"  value="'.$modid.'"> '.$row_modhooks['display_txt'].' </li>'; 
                          }
                          echo '</ul>';
                          }
                                                     
                     }
                     echo '</ul>';
                                              
                }
                                        
             }
             echo '</ul>';
    }else{
          echo 'No Concern Added Yet! Pls Add a Concer First';
    }
                                
?>

问题根源

  1. 数组未重置导致重复遍历:在遍历sister_concern的while循环中,$namearray[]=$name;会不断将当前项追加到数组中,后续的foreach($namearray as $data)会遍历整个数组,导致第N次循环时输出N次主复选框(包含之前所有的sister concern)。同理,$modearray[]=$modname;也会导致模块被重复输出。
  2. 多余的foreach循环:代码中完全不需要用数组存储名称再遍历,直接输出当前循环的$name和$rowmodule['Name']即可,foreach属于冗余逻辑。

修复后的代码

<?php
$sql_concern = "SELECT * FROM sister_concern WHERE Base_user='$User_id' AND Status='Active'";
$result_concern = mysqli_query($link, $sql_concern);

if (mysqli_num_rows($result_concern) > 0) {
    echo '<ul>';
    while ($row = mysqli_fetch_array($result_concern)) {
        $sisid = $row['Id'];
        $name = $row['Name'];

        // 直接输出当前sister concern的复选框
        echo '<li style="list-style-type:none;"><input type="checkbox" name="sister_concern" class="chkMainConcern" id="chkMainConcern' . $sisid . '" value="' . $sisid . '" > ' . $name . ' </li>';

        // 获取当前concern对应的模块
        $sql_module = "SELECT * FROM Module WHERE Status='Active'";
        $result_module = mysqli_query($link, $sql_module);

        echo '<ul class="modulename' . $sisid . '" style="display:none;">';
        while ($rowmodule = mysqli_fetch_array($result_module)) {
            $modid = $rowmodule['Id'];
            $modname = $rowmodule['Name'];

            // 直接输出当前模块的复选框
            echo '<li style="list-style-type:none;"><input type="checkbox" value="' . $modid . '"> ' . $modname . ' </li>';

            // 获取当前模块的权限
            $sql_modhooks = "SELECT * FROM Module_hooks WHERE Status='Active' AND ModuleID='$modid'";
            $result_modhooks = mysqli_query($link, $sql_modhooks);
            echo '<ul class="modulehooks' . $modid . '" style="display:none;">';
            while ($row_modhooks = mysqli_fetch_array($result_modhooks)) {
                echo '<li style="list-style-type:none;"><input type="checkbox" value="' . $modid . '"> ' . $row_modhooks['display_txt'] . ' </li>';
            }
            echo '</ul>';
        }
        echo '</ul>';
    }
    echo '</ul>';
} else {
    echo 'No Concern Added Yet! Pls Add a Concern First';
}
?>

额外优化建议

  • SQL注入风险:当前代码直接将变量拼接到SQL语句中,存在注入风险,建议使用mysqli_prepare预处理语句替代。
  • 代码冗余优化:可将模块、权限查询封装为独立函数,提升代码复用性与可读性。
  • 样式分离:将内联样式转移到外部CSS文件,便于统一维护。

内容的提问来源于stack exchange,提问作者Mithu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:45:37