《PHP實(shí)例:php實(shí)現(xiàn)無限級(jí)分類查詢(遞歸、非遞歸)》要點(diǎn):
本文介紹了PHP實(shí)例:php實(shí)現(xiàn)無限級(jí)分類查詢(遞歸、非遞歸),希望對您有用。如果有疑問,可以聯(lián)系我們。
PHP教程做PHP這么長時(shí)間,發(fā)現(xiàn)后臺(tái)管理系統(tǒng)不可少的一個(gè)應(yīng)用模塊就是對欄目的分類,一般情況下欄目都要做成是無限級(jí)的,也就是說每個(gè)欄目理論上都可以添加子欄目.在我看來這種情況處理起來整體上說也不是很復(fù)雜,唯一一個(gè)相對來說較難的點(diǎn)是無限級(jí)欄目的查詢.
PHP教程下面就這種情況我來向大家做一個(gè)簡單的介紹,對于這種無限級(jí)欄目的查詢一般情況下有兩種方式,其中一種就是使用棧的機(jī)制,另一種是使用遞歸函數(shù)的方式(當(dāng)然遞歸函數(shù)實(shí)現(xiàn)機(jī)制也是借助于棧來實(shí)現(xiàn)的).就這兩種方式下面我們分別介紹.
PHP教程遞歸函數(shù)實(shí)現(xiàn)方式
PHP教程上面提到,遞歸函數(shù)的也是借助于棧的機(jī)制實(shí)現(xiàn)的,但是底層對于棧的處理對于程序員來說都是透明的,程序員只需要關(guān)心應(yīng)用的實(shí)現(xiàn)邏輯.所以說使用遞歸處理上述問題理解起來比擬容易,代碼也比擬簡潔.
PHP教程既然使用遞歸函數(shù),看名字我們就知道必需借助于自定義的函數(shù).我先大概說一下其實(shí)現(xiàn)思路,具體細(xì)節(jié)我們反映在代碼中.
PHP教程對于每一層的函數(shù)其主要做的工作就是查找父Id為當(dāng)前Id的欄目,查找到以后再次調(diào)用自身函數(shù),將查找到的欄目的id作為下一層的父id.
PHP教程其流程圖如下
PHP教程
PHP教程圖一
PHP教程不知道對于上面的解釋大家能不能理解,沒關(guān)系我們下面直接看代碼
PHP教程
<?php
/**
* 個(gè)人博客:跡憶博客
* 博客地址:www.onmpw.com
* 遞歸實(shí)現(xiàn)無限極分類
*/
$channels = array(
array('id'=>1,'name'=>"衣服",'parId'=>0),
array('id'=>2,'name'=>"書籍",'parId'=>0),
array('id'=>3,'name'=>"T恤",'parId'=>1),
array('id'=>4,'name'=>"褲子",'parId'=>1),
array('id'=>5,'name'=>"鞋子",'parId'=>1),
array('id'=>6,'name'=>"皮鞋",'parId'=>5),
array('id'=>7,'name'=>"運(yùn)動(dòng)鞋",'parId'=>5),
array('id'=>8,'name'=>"耐克",'parId'=>7),
array('id'=>9,'name'=>"耐克",'parId'=>3),
array('id'=>10,'name'=>"鴻星爾克",'parId'=>7),
array('id'=>11,'name'=>"小說",'parId'=>2),
array('id'=>12,'name'=>"科幻小說",'parId'=>11),
array('id'=>13,'name'=>"古典名著",'parId'=>11),
array('id'=>14,'name'=>"文學(xué)",'parId'=>2),
array('id'=>15,'name'=>"四書五經(jīng)",'parId'=>14)
);
$html = array();
/**
* 遞歸查找父id為$parid的結(jié)點(diǎn)
* @param array $html 依照父-》子的結(jié)構(gòu)存放查找出來的結(jié)點(diǎn)
* @param int $parid 指定的父id
* @param array $channels 數(shù)據(jù)數(shù)組
* @param int $dep 遍歷的深度,初始化為1
*/
function getChild(&$html,$parid,$channels,$dep){
/*
* 遍歷數(shù)據(jù),查找parId為參數(shù)$parid指定的id
*/
for($i = 0;$i<count($channels);$i++){
if($channels[$i]['parId'] == $parid){
$html[] = array('id'=>$channels[$i]['id'],'name'=>$channels[$i]['name'],'dep'=>$dep);
getChild($html,$channels[$i]['id'],$channels,$dep+1);
}
}
}
getChild($html,0,$channels,1);
?>
PHP教程這是遞歸實(shí)現(xiàn)無限級(jí)欄目查詢的核心代碼,結(jié)合圖一對其實(shí)現(xiàn)流程應(yīng)該有一個(gè)較清晰的認(rèn)識(shí).
PHP教程非遞歸,即使用棧機(jī)制實(shí)現(xiàn)無限級(jí)欄目的查詢
PHP教程在上面我們大概介紹了一下使用遞歸的方式實(shí)現(xiàn)無限級(jí)欄目的查詢,下面我們簡單介紹一下非遞歸的方式.雖說不用遞歸函數(shù)的方式,但是鑒于無限級(jí)欄目的結(jié)構(gòu)頁需要參考遞歸的實(shí)現(xiàn)機(jī)制――棧的機(jī)制,辦理這一問題.
PHP教程在上學(xué)的時(shí)候老師就說,其實(shí)棧的核心機(jī)制也就四個(gè)字:先進(jìn)后出.
PHP教程在這對于棧的機(jī)制不多說,主要說一下如何借助棧實(shí)現(xiàn)無限級(jí)欄目查詢.
PHP教程1. 首先將頂級(jí)欄目壓入棧中
PHP教程2. 將棧頂元素出棧
PHP教程3. 將出棧元素存入數(shù)組中,標(biāo)記其深度(其深度就是在其父欄目的深度上面加1)
PHP教程4. 以出棧的元素為父欄目,查找其子欄目
PHP教程5. 將查找到的子欄目入棧,重復(fù)步驟2
PHP教程6. 判斷棧為空的話,流程結(jié)束;
PHP教程通過對以上步驟的翻譯,可以將這些步驟翻譯成PHP代碼,其核心代碼如下
PHP教程
<?php
/**
* 個(gè)人博客:跡憶博客
* 博客地址:www.onmpw.com
*使用非遞歸,即使用棧的方式實(shí)現(xiàn)欄目的無限極分類查詢
*/
$channels = array(
array('id'=>1,'name'=>"衣服",'parId'=>0),
array('id'=>2,'name'=>"書籍",'parId'=>0),
array('id'=>3,'name'=>"T恤",'parId'=>1),
array('id'=>4,'name'=>"褲子",'parId'=>1),
array('id'=>5,'name'=>"鞋子",'parId'=>1),
array('id'=>6,'name'=>"皮鞋",'parId'=>5),
array('id'=>7,'name'=>"運(yùn)動(dòng)鞋",'parId'=>5),
array('id'=>8,'name'=>"耐克",'parId'=>7),
array('id'=>9,'name'=>"耐克",'parId'=>3),
array('id'=>10,'name'=>"鴻星爾克",'parId'=>7),
array('id'=>11,'name'=>"小說",'parId'=>2),
array('id'=>12,'name'=>"科幻小說",'parId'=>11),
array('id'=>13,'name'=>"古典名著",'parId'=>11),
array('id'=>14,'name'=>"文學(xué)",'parId'=>2),
array('id'=>15,'name'=>"四書五經(jīng)",'parId'=>14)
);
$stack = array(); //定義一個(gè)空棧
$html = array(); //用來保留各個(gè)欄目之間的關(guān)系以及該欄目的深度
/*
* 自定義入棧函數(shù)
*/
function pushStack(&$stack,$channel,$dep){
array_push($stack, array('channel'=>$channel,'dep'=>$dep));
}
/*
* 自定義出棧函數(shù)
*/
function popStack(&$stack){
return array_pop($stack);
}
/*
* 首先將頂級(jí)欄目壓入棧中
*/
foreach($channels as $key=>$val){
if($val['parId'] == 0)
pushStack($stack,$val,0);
}
/*
* 將棧中的元素出棧,查找其子欄目
*/
do{
$par = popStack($stack); //將棧頂元素出棧
/*
* 查找以此欄目為父級(jí)欄目的id,將這些欄目入棧
*/
for($i=0;$i<count($channels);$i++){
if($channels[$i]['parId'] == $par['channel']['id']){
pushStack($stack,$channels[$i],$par['dep']+1);
}
}
/*
* 將出棧的欄目以及該欄目的深度保留到數(shù)組中
*/
$html[] = array('id'=>$par['channel']['id'],'name'=>$par['channel']['name'],'dep'=>$par['dep']);
}while(count($stack)>0);
PHP教程上面就是使用非遞歸方式實(shí)現(xiàn)的.
PHP教程下載代碼:https://github.com/onmpw/phpApp
PHP教程總結(jié)
PHP教程上面兩種方式各有利弊,雖然實(shí)現(xiàn)形式上面不同,但是鑒于無限級(jí)欄目的結(jié)構(gòu),二者實(shí)現(xiàn)的機(jī)制都是相同的――都借助棧的方式來實(shí)現(xiàn).在現(xiàn)實(shí)情況中,我們要根據(jù)現(xiàn)實(shí)情況的必要選擇一種方式來實(shí)現(xiàn).
《PHP實(shí)例:php實(shí)現(xiàn)無限級(jí)分類查詢(遞歸、非遞歸)》是否對您有啟發(fā),歡迎查看更多與《PHP實(shí)例:php實(shí)現(xiàn)無限級(jí)分類查詢(遞歸、非遞歸)》相關(guān)教程,學(xué)精學(xué)透。維易PHP學(xué)院為您提供精彩教程。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/7385.html