你好,欢迎访问我的博客!登录
当前位置:首页 - 技术 - 正文 君子好学,自强不息!

php递归函数遍历树形结构方法和技巧

2018-06-13 08:25:45技术admin26°c
A+ A-

 首先到数据库取数据,放到一个数组, 然后把数据转化为一个树型状的数组, 最后把这个树型状的数组转为html代码。 也可以将第二步和第三步合为一步

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

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

public function tree2(){
        $r = array(
            array(
                'id'=>1,
                'name'=>'智慧教育',
                'parent_id'=>0,
                'level'=>0 //一级分类
            ),
            array(
                'id'=>2,
                'name'=>'学校列表',
                'parent_id'=>1,
                'level'=>1 //二级分类
            ),
            array(
                'id'=>4,
                'name'=>'智慧医疗',
                'parent_id'=>0,
                'level'=>0 //一级分类
            ),
            array(
                'id'=>5,
                'name'=>'医院列表',
                'parent_id'=>4,
                'level'=>1 //二级分类
            ),
            array(
                'id'=>6,
                'name'=>'名医列表',
                'parent_id'=>5,
                'level'=>2 //三级分类
            )
        );
        //输出为select标签:
        echo '<h1>PHPTree</h1>';
        echo '<select  style="width:300px;">';
        foreach($r as $item){
            echo '<option>';
            //根据所在的层次缩进
            echo str_repeat('|—',$item['level']);
            echo $item['name'];
            echo '</option>';
        }
        echo '</select>';
    }

  页面效果图是这样的。

php递归函数遍历树形结构方法和技巧

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

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

public function tree3(){
        //从表中查到所有栏目
        $cat = M('category');
        $allcat = $cat ->order('listorder ASC') ->select();
        //输出select标签
        echo '<h2>栏目tree</h2>';
        echo '<select  style="width:300px;">';
        foreach ($allcat as $val) {
            if($val[parentid] == 0){
                echo '<option>';
                echo $val['catname'];
                echo '</option>';
            }
            foreach ($allcat as $value) {
                if($val[id] == $value[parentid]){
                    echo '<option>';
                    echo '|—'.$value['catname'];
                    echo '</option>';
                }
            }
        }
        ......
    }

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

这里采用递归的方式

  这样就可以不断重复查询本身的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);
    }

  页面显示效果图如下:

php递归函数遍历树形结构方法和技巧

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

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  选择分享方式
  移步手机端
php递归函数遍历树形结构方法和技巧

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
标签:

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>


  用户登录