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="width: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="width: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);
    }

  頁面顯示效果圖如下:

    

  這樣就實現了多級欄目的顯示。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM