您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關怎么在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('  ',$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; } }
類中函數主要采取了遞歸函數的方法,如果理解深刻理解遞歸函數,其余的部分也就水到渠成了。我會在后面的部分詳細介紹實現遞歸函數的三種方法。
我們再來看一個實例:
首先建立分類信息表:
CREATE TABLE IF NOT EXISTS `category` ( `categoryId` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `parentId` smallint(5) unsigned NOT NULL DEFAULT '0', `categoryName` varchar(50) NOT NULL, PRIMARY KEY (`categoryId`) ) ;
插入若干數據:
INSERT INTO `category` (`categoryId`, `parentId`, `categoryName`) VALUES (1, 0, 'php'), (2, 0, 'java'), (3, 0, 'c/c++'), (4, 1, 'php基礎'), (5, 1, 'php開源資料'), (6, 1, 'php框架'), (7, 2, 'java Se'), (8, 2, 'java EE'), (9, 2, 'java Me'), (10, 3, 'c/c++基礎編程'), (11, 3, 'c/c++系統開發'), (12, 3, 'c嵌入式編程'), (13, 3, 'c++應用開發'), (14, 13, 'c++桌面應用開發'), (15, 13, 'c++游戲開發');
下面是php代碼:
<?php /* php無限極分類 */ //獲取某分類的直接子分類 function getSons($categorys,$catId=0){ $sons=array(); foreach($categorys as $item){ if($item['parentId']==$catId) $sons[]=$item; } return $sons; } //獲取某個分類的所有子分類 function getSubs($categorys,$catId=0,$level=1){ $subs=array(); foreach($categorys as $item){ if($item['parentId']==$catId){ $item['level']=$level; $subs[]=$item; $subs=array_merge($subs,getSubs($categorys,$item['categoryId'],$level+1)); } } return $subs; } //獲取某個分類的所有父分類 //方法一,遞歸 function getParents($categorys,$catId){ $tree=array(); foreach($categorys as $item){ if($item['categoryId']==$catId){ if($item['parentId']>0) $tree=array_merge($tree,getParents($categorys,$item['parentId'])); $tree[]=$item; break; } } return $tree; } //方法二,迭代 function getParents2($categorys,$catId){ $tree=array(); while($catId != 0){ foreach($categorys as $item){ if($item['categoryId']==$catId){ $tree[]=$item; $catId=$item['parentId']; break; } } } return $tree; } //測試 部分 $pdo=new PDO('mysql:host=localhost;dbname=test','root','8888'); $stmt=$pdo->query("select * from category order by categoryId"); $categorys=$stmt->fetchAll(PDO::FETCH_ASSOC); $result=getSons($categorys,1); foreach($result as $item) echo $item['categoryName'].'<br>'; echo '<hr>'; $result=getSubs($categorys,0); foreach($result as $item) echo str_repeat(' ',$item['level']).$item['categoryName'].'<br>'; echo '<hr>'; $result=getParents($categorys,7); foreach($result as $item) echo $item['categoryName'].' >> '; echo '<hr>'; $result=getParents2($categorys,15); foreach($result as $item) echo $item['categoryName'].' >> '; ?>
看下最終結果吧
關于怎么在php中利用遞歸實現一個無限級分類就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。