zoukankan      html  css  js  c++  java
  • PHP树结构,实现无限分级

    一、从数据库查出来的数据需要id、parentid、level。

      id唯一识别栏目,parentid为该栏目所属父类id,level标示该栏目是几级栏目。以下代码就可以实现一个简单的树结构。

     1 public function tree2(){
     2         $r = array(
     3             array(
     4                 'id'=>1,
     5                 'name'=>'智慧教育',
     6                 'parent_id'=>0,
     7                 'level'=>0 //一级分类
     8             ),
     9             array(
    10                 'id'=>2,
    11                 'name'=>'学校列表',
    12                 'parent_id'=>1,
    13                 'level'=>1 //二级分类
    14             ),
    15             array(
    16                 'id'=>4,
    17                 'name'=>'智慧医疗',
    18                 'parent_id'=>0,
    19                 'level'=>0 //一级分类
    20             ),
    21             array(
    22                 'id'=>5,
    23                 'name'=>'医院列表',
    24                 'parent_id'=>4,
    25                 'level'=>1 //二级分类
    26             ),
    27             array(
    28                 'id'=>6,
    29                 'name'=>'名医列表',
    30                 'parent_id'=>5,
    31                 'level'=>2 //三级分类
    32             )
    33 
    34         );
    35         //输出为select标签:
    36         echo '<h1>PHPTree</h1>';
    37         echo '<select  style="300px;">';
    38         foreach($r as $item){
    39             echo '<option>';
    40             //根据所在的层次缩进
    41             echo str_repeat('|—',$item['level']);
    42             echo $item['name'];
    43             echo '</option>';
    44         }
    45         echo '</select>';
    46     }

      页面效果图是这样的。

        

    二、但是一般表结构中是没有level的。

      这样就需要多层循环嵌套加if判断,先循环显示父级栏目parentid=0,及它就是一级栏目;然后再循环根据parentid与一级栏目的id判断,如果相等则显示对应的栏目,二级栏目就显示出来啦,以此类推,可以显示所有栏目。但这只适合已知栏目层数且层数不多的情况,因为要根据层数来判断遍历的次数。且如果层数过多,代码量就会很大。

     1 public function tree3(){
     2         //从表中查到所有栏目
     3         $cat = M('category');
     4         $allcat = $cat ->order('listorder ASC') ->select();
     5 
     6         //输出select标签
     7         echo '<h2>栏目tree</h2>';
     8         echo '<select  style="300px;">';
     9         foreach ($allcat as $val) {
    10             if($val[parentid] == 0){
    11                 echo '<option>';
    12                 echo $val['catname'];
    13                 echo '</option>';
    14             }
    15             foreach ($allcat as $value) {
    16                 if($val[id] == $value[parentid]){
    17                     echo '<option>';
    18                     echo '|—'.$value['catname'];
    19                     echo '</option>';
    20                 }
    21             }
    22         }
    23         ......
    24     }

      那怎么知道栏目层数,或者怎么判断该栏目下面还有没有子栏目呢?

    三、这里采用递归的方式

      这样就可以不断重复查询本身的pid等于上一级id的数据,通过判断查到的数据是否为空来判断它有没有子栏目。

      还有一个问题就是根据级别设置缩进,这样看着有层次感。那这个怎么实现呢?在php中有一个字符串函数str_repeat(),两个参数,第一个表示要重复的字符串,第二个是重复的次数。

      代码片段如下:

    //递归实现无限级菜单
        public function tree2($pid=0,$level=0){
            $cat = M('category');
            $data = $cat ->where("parentid = $pid") ->field('id,catname,parentid') ->select();
    
            $level ++;
            if(!empty($data)){
                $tree = array();
                foreach ($data as $val) {
                    $val['catname'] = str_repeat('|—', $level-1).$val['catname'];
                    $child = $this ->tree2($val[id],$level);
                    $tree[] = array('self'=>$val,'child'=>$child,'level'=>$level);
                }
            }
            return $tree;
        }
    
        function test(){
            $allcat = $this ->tree2(0);
            dump(json_encode($allcat));
        }

       上面tree2方法找到了所有栏目,并组装到tree数组中,tree是一个多维数组,现在要从数组中取出所有栏目名称catname,同样递归调用,代码如下:

    //遍历找出所有catname
        function getcatname($array){
           if(is_array($array)){
             foreach ($array as $key=>$value ){
               if(is_array($value)){
                 $this ->getcatname($value);           
                }else{
                    $temp = array('key'=>$key,'value'=>$value);
                     if ($temp['key'] == 'catname') {
                         echo $temp['value']."<br/>";
                     }
                }
             }
           }
        }
    
        function test(){
            $allcat = $this ->tree2(0);
            $this ->getcatname($allcat);
        }

      页面显示效果图如下:

        

      这样就实现了多级栏目的显示。

  • 相关阅读:
    MySQL binlog中 format_desc event格式解析
    位bit和字节Byte
    MySQL利用mysqlbinlog模拟增量恢复
    mysqldump参数 --master-data详解
    开启MySQL二进制日志
    设置花里胡哨的Xshell字体与背景颜色(超全)
    Python操作MySQL数据库
    给定一个由括号([{)]}其中之一或多个组成的字符串判断是否符合左右括号成对标准,不同括号可任意嵌套
    给定一个字符串str,将str中连续两个字符为a的字符替换为b(一个或连续超过多个字符a则不替换)
    不使用局部变量和for循环或其它循环打印出如m=19,n=2結果为2 4 8 16 16 8 4 2形式的串
  • 原文地址:https://www.cnblogs.com/rendd/p/6118085.html
Copyright © 2011-2022 走看看