php利用遞迴函式實現無限級分類

傑楓Jeff發表於2015-08-05

  相信很多學php的很多小夥伴都會嘗試做一個網上商城作為提升自己技術的一種途徑。各種對商品分類,商品名之類的操作應該是得心應手,那麼就可以嘗試下無限級分類列表的製作了。

  什麼是無限級分類?

  無限級分類是一種分類技巧,例如部門組織,文章分類,學科分類等常用到無限級分類,將其簡單理解成分類就好了。其實我們仔細想一下,生活中的分類簡直太多了,衣服可以分為男裝和女裝,也可以分為上衣和褲子,也可以根據年齡段分類。分類無處不在,分類顯得“無限”。我這裡就不說無限分類的必要性了。

  無限級分類原理簡介

  無限分類看似"高大上",實際上原理是非常簡單的 。無限分類不僅僅需要程式碼的巧妙性,也要依託資料庫設計的合理性。要滿足無限級分類,資料庫需要有兩個必須的欄位,id,pid。id用來標識自身,而pid則是用來表明父級id。也就是說,每個分類記錄不僅描述了自身,還描述了與其關心最為緊密的另一個id。看似複雜的事情被這樣一個小技巧解決了。

  閒話不多說,該展現本文的例項了。

  作為一個狂熱海賊迷,這篇的例項我就以《海賊王》人物組織做案例。

  資料庫準備: 

  建表onepiece:

create table onepiece(
    id int auto_increment,
    pid int not null,
    name varchar(225) not null,
    primary key(id)
);

   插入測試資料:

insert onepiece values
    (1,0,'海軍'),
    (2,0,'海賊'),
    (3,0,'革命軍'),
    (4,1,'青雉'),
    (5,1,'赤犬'),
    (6,1,'黃猿'),
    (7,2,'四皇'),
    (8,2,'七武海'),
    (9,2,'草帽海賊團'),
    (10,9,'索隆'),
    (11,7,'香克斯'),
    (12,8,'多弗朗明哥'),
    (13,8,'克洛克達爾');

  這裡還是科普下海賊王裡面的設定:世界分為三大陣營:海軍,海賊,革命軍。海軍有大將:青雉,赤犬,黃猿。海賊有:四皇,七武海,草帽海賊團。四皇有香克斯,七武海有多弗朗明哥,克洛克達爾,草帽海賊團有索隆。(打個廣告:海賊王真的很好看)。

  最終目的:

  我們今天製作的是兩種形式的無限級分類形式,一種是下拉選單式,一種則是導航Link式的。直接上效果圖了:

下拉選單式導航Link式

  例項程式碼:

  我封裝了一個Unlimited類,用來呼叫diaplayList()展現下拉選單形式,呼叫diaplayLink展現導航Link分類。也可以增加(addNodes())和刪除(deleteNodes)分類。

  

<?php

class Unlimited{
    protected $mysqli;
    public function __construct($config){
        $this->mysqli=new mysqli($config['host'],$config['user'],$config['pwd']);
        $this->mysqli->select_db($config['db']);
        $this->mysqli->set_charset('utf8');
        if ($this->mysqli->connect_errno) {
            echo $this->mysqli->connect_error;
        }
    }    

    private function getList($pid=0,&$result=array(),$spac=0){
        $spac=$spac+2;
        $sql="select * from onepiece where pid={$pid}";
        $rs=$this->mysqli->query($sql);
        while($row=$rs->fetch_assoc()) {
            $row['name']=str_repeat('&nbsp;&nbsp',$spac).$row['name'];
            $result[]=$row;
            $this->getList($row['id'],$result,$spac);            
        }
        return $result;
    }
    /**
     * 展現下拉選單式分類
     * @return [type] 
     */
    public function displayList(){
        $rs=$this->getList();
        $str="<select name='cate'>";

        foreach ($rs as $key => $val) {
            $str.="<option >{$val['name']}</option>";
        }
        $str.="</select>";
        return $str;
    }

    private function getLink($cid,&$result=array()){
        $sql="select * from onepiece where id={$cid}";
        $rs=$this->mysqli->query($sql);
        if($row=$rs->fetch_assoc()){
            $result[]=$row;
            $this->getLink($row['pid'],$result);
        }
        return array_reverse($result);
    }
    /**
     * 展現導航Link
     * @param  [type] $cid [description]
     * @return [type]      [description]
     */
    public function displayLink($cid){
        $rs=$this->getLink($cid);
        $str='';
        foreach ($rs as $val) {
            $str.="<a href=''>{$val['name']}</a>>";
        }

        return $str;
    }
    /**
     * 增加分類
     * @param [type] $pid  父類id
     * @param [type] $name 本類名
     */
    public function addNodes($pid,$name){
        $sql="insert into onepiece values('',{$pid},'".$name."')";
        if($this->mysqli->query($sql)){

            return true;

        }
    }
    /**
     * 刪除分類
     * @param  [type] $id 本類id
     * @return [type]     
     */
    public function deleteNodes($id){
        $sql="select * from onepiece where pid ={$id}";
        $rs=$this->mysqli->query($sql);
        if($row=$rs->fetch_assoc()){
            $mes="還有子元素,請勿刪除";
        }else{
            $sql="delete from onepiece where id={$id}";
            if($this->mysqli->query($sql)){
                $mes="刪除成功";
            }
        }
        return $mes;
    }
}

  類中函式主要採取了遞迴函式的方法,如果理解深刻理解遞迴函式,其餘的部分也就水到渠成了。後面的php遞迴函式的三種方法詳細介紹了php遞迴函式的原理。

相關文章