php 無限分類遞迴及其排序詳細解讀

2021-07-27 16:40:32 字數 3749 閱讀 9021

在各種欄目以及分類設定中,無限分類經常會被用到,而無限分類在進行排序的時候必然要用到遞迴,這裡進行一次詳細的分析解讀。

首先我們先了解一下遞迴函式:

遞迴函式在語言學習的時候會單獨拿出來學習,因為它非常常用,本質上來講遞迴函式就是呼叫自己的函式。

舉個例子:

<?php 

function test()

echo $a."";}

test();

test函式裡面又再呼叫了自身,這就是俗稱的遞迴函式!遞迴函式都有條件設定,不然的會無限迴圈下去,這樣會導致程式奔潰。所以一般來講我總結遞迴函式有兩個特點:

乙個是記錄條件值,記錄的條件值必須保證不會再下一次呼叫時丟失。

test函式裡$a便是記錄條件值,它是依靠使用static關鍵字來保證記錄每次增加的數值不會再下一次呼叫test()函式而丟失,因為函式中static修飾的變數僅僅在第一次初始化,並保留變數值。所以只要保證這一點,不光static,其他的方式也可以達到目的,例如global還有&修飾符。

另乙個是條件檢查。test裡面對$a大小的限制就是該條件的檢查過程。

test函式中if($a<10)就是這個條件檢查的過程,它限制了test()函式對自身的呼叫,這樣就可以防止無限呼叫導致程式奔潰。

函式a內部呼叫另外的函式b,如果b函式沒有完成,那麼a函式就會一直等待下去,直到b函式完成,才會回到a函式繼續執行。遞迴的過程中利用了這個特性,正是這個能幫助我們對無限分類進行排序,用上面test()遞迴函式說明:

上面test()列印出來的結果是:

10,10,10,10,10,10,10,10,10,10,10

可能和很多人想的不一樣,大概有許多人會覺得不應該是0,1,2,3,4,5,6,7,8,9,10這樣的結果嗎?

這是因為函式test呼叫過程中,只要$a<10,就會呼叫自身的test(),每次呼叫的test()都沒有到達echo處,也就是每次呼叫的test函式並沒有完結,直到$a遞增到了10,才第一次echo $a,這個時候$a已經是10了,因此第乙個10實際是遞迴了11次後的$a,第十一次遞迴的test由於不符合<10的條件該函式完結,這個時候才開始回到遞迴第十次test函式裡執行echo,這個時候由於$a是靜態變數,值已經是10了,因此echo出的結果是10,下面依次回到之前的test函式完成前面未完成的echo步驟,因此echo出11個10,最後乙個10實際是第一次執行test函式的echo結果。

無限分類的排序完成也是用的這個原理,遞迴排序函式不斷的通過parentid等於上一級id的子類來匹配該類別的子類別,只要找到第乙個子類,就用找到的這個子類的id去找下一級的子類,直到沒有更下級的子類的時候,才返回上一級接著繼續找,找到後又開始尋找該子類下一級子類,直到沒有為止才返回,這個過程不斷迴圈。可能用文字不太能理解,下面的例項中我會畫出圖例,請先往後看。

我們先來看無限分類的資料er圖:

例如乙個裙子的類目,它有父類別**,**又屬於衣服的類目,假定裙子的id為3,**為2,衣服為1,那麼裙子的parentid就是直接的上級類目裙子的id,因此parentid=2,而child是裙子所在的樹形結構上全部的祖先元素id,那麼child應該是1,2,3,因此裙子的深度deep為3,這裡我假設的是用,隔開,也可以用其他的符號隔開,title不用說就是裙子。

具體我們來看這個樹形結構:

從樹形結構分類還可以繼續延伸下去,上一級的id是下一級的parentid,就是通過id和parent這兩個列來實現基本的無限分類的,再進行無限分類的遞迴排序的時候也是依靠這兩個欄位的關係。

下面是乙個無限分類的表結構以及資料的例子:

為了更清楚下面畫了樹形圖:

上一代的類別的id就是自身的parentid,最高一級的parentid則為0,這點非常重要,是無限分類的排序的依據。

我們所要的無限分類排序效果應該是各欄目下的子欄目都放到該欄目下方,用id進行排序,我們要的效果就是下面這樣,為了方便檢視我用了tab以及|——來間隔區分欄目之間的關係:

衣服|——**

|——休閒上衣

|——短袖

|——長袖

|——休閒褲

|——**

|——**上衣

|——**下裝

|——牛仔褲

|——裙子

由於類別可以無限延伸下去,所以這裡明顯我們需要使用遞迴函式進行排序分類。

獲取資料所有結果,並按id排序

$mysqli=new mysqli('localhost','root','root','test')or die("連線失敗");

$mysqli->set_charset("utf8");

$re=$mysqli->query("select * from col order by id asc");

$result=$re->fetch_all(mysqli_assoc);

遞迴排序函式

function recursion($result,$parentid=0)

}return $list;

}

這個時候我們就能得到按類別排序好的陣列了,但是如果要有相應的格式,例如上面的|——,就需要對函式進行改進。

function recursion($result,$parentid=0,$format="|--")

/*將該類別的資料放入list中*/

$list=$v;

recursion($result,$v['id'],"  ".$format);}}

return $list;

}$list=recursion($result,0,'|--');

這樣排序的結果如下:

整個遞迴函式的執**況大概是什麼樣的,我們接上面說過的要畫的例項圖,看圖後就很清楚這個原理了,這個圖只畫了部分,不過足夠理解這個過程了:

PHP 無限級分類 遞迴

arr array array id 1,name 電腦 pid 0 array id 2,name 手機 pid 0 array id 3,name 筆記本 pid 1 array id 4,name 台式電腦 pid 1 array id 5,name 智慧型機 pid 2 array id 6...

PHP遞迴實現無限級分類

在一些複雜的系統中,要求對資訊欄目進行無限級的分類,以增強系統的靈活性。那麼php是如何實現無限級分類的呢?我們在本文中使用遞迴演算法並結合mysql資料表實現無限級分類。在一些複雜的系統中,要求對資訊欄目進行無限級的分類,以增強系統的靈活性。那麼php是如何實現無限級分類的呢?我們在本文中使用遞迴...

PHP實現遞迴無限級分類

在一些複雜的系統中,要求對資訊欄目進行無限級的分類,以增強系統的靈活性。那麼php是如何實現無限級分類的呢?我們在本文中使用遞迴演算法並結合mysql資料表實現無限級分類。遞迴,簡單的說就是一段程式 的重複呼叫,當把 寫到乙個自定義函式中,將引數等變數儲存,函式中重複呼叫函式,直到達到某個條件才跳出...