php 無限級(jí)分類學(xué)習(xí)參考之對(duì)ecshop無限級(jí)分類的解析 帶詳細(xì)注釋
function cat_options($spec_cat_id, $arr)
{
static $cat_options = array();
if (isset($cat_options[$spec_cat_id]))
{
return $cat_options[$spec_cat_id];
}
/*
初始化關(guān)鍵參數(shù):
$level:當(dāng)前子節(jié)點(diǎn)深度
$last_cat_id:當(dāng)前父節(jié)點(diǎn)ID
$options:帶有縮進(jìn)級(jí)別的數(shù)組
$cat_id_array:沿同一路徑的父節(jié)點(diǎn)依次進(jìn)駐
$level_array:該節(jié)點(diǎn)的子節(jié)點(diǎn)深度,也是依次進(jìn)駐
*/
if (!isset($cat_options[0]))
{
$level = $last_cat_id = 0;
$options = $cat_id_array = $level_array = array();
while (!empty($arr))//如果還有待構(gòu)造的節(jié)點(diǎn)則繼續(xù)遍歷
{
foreach ($arr AS $key => $value)
{
$cat_id = $value['cat_id'];
//一級(jí)分類結(jié)點(diǎn)
if ($level == 0 && $last_cat_id == 0)
{
if ($value['parent_id'] > 0)
{
break;
}
$options[$cat_id] = $value;
$options[$cat_id]['level'] = $level;
$options[$cat_id]['id'] = $cat_id;
$options[$cat_id]['name'] = $value['cat_name'];
//遍歷過了就不再遍歷
unset($arr[$key]);
if ($value['has_children'] == 0)
{
continue;
}
$last_cat_id = $cat_id;//下層結(jié)點(diǎn)的父親結(jié)點(diǎn)
$cat_id_array = array($cat_id);
$level_array[$last_cat_id] = ++$level;
continue;
}
//當(dāng)前結(jié)點(diǎn)的父親結(jié)點(diǎn)ID等于它的上一級(jí)結(jié)點(diǎn)ID
if ($value['parent_id'] == $last_cat_id)
{
$options[$cat_id] = $value;
$options[$cat_id]['level'] = $level;
$options[$cat_id]['id'] = $cat_id;
$options[$cat_id]['name'] = $value['cat_name'];
unset($arr[$key]);//遍歷過了就不再遍歷
//如果當(dāng)前結(jié)點(diǎn)有孩子則當(dāng)前結(jié)點(diǎn)要進(jìn)駐,但不再遍歷;反之不進(jìn)駐也不再遍歷
if ($value['has_children'] > 0)
{
if (end($cat_id_array) != $last_cat_id)
{
$cat_id_array[] = $last_cat_id;
}
$last_cat_id = $cat_id;//當(dāng)現(xiàn)結(jié)點(diǎn)做為下一級(jí)結(jié)點(diǎn)的新的父親結(jié)點(diǎn)
$cat_id_array[] = $cat_id;//進(jìn)駐
$level_array[$last_cat_id] = ++$level;//當(dāng)前結(jié)點(diǎn)的下一級(jí)結(jié)點(diǎn)深度
}
}
elseif ($value['parent_id'] > $last_cat_id)
{//如果當(dāng)前結(jié)點(diǎn)父親深度大于目前父親結(jié)點(diǎn)的深度則進(jìn)行下一輪循環(huán)
break;
}
}//endforeach
$count = count($cat_id_array);
if ($count > 1)
{
//取出最后進(jìn)駐的父親節(jié)點(diǎn)作為當(dāng)前父親節(jié)點(diǎn)
$last_cat_id = array_pop($cat_id_array);
}
elseif ($count == 1)
{
if ($last_cat_id != end($cat_id_array))
{
//進(jìn)駐的父親結(jié)點(diǎn)只有一個(gè)時(shí)并且沒有作為當(dāng)前父親節(jié)點(diǎn)時(shí)把它取出
$last_cat_id = end($cat_id_array);
}
else
{ //否則最后取出的父親結(jié)點(diǎn)一定是一級(jí)分類結(jié)點(diǎn)
$level = 0;
$last_cat_id = 0;
$cat_id_array = array();
continue;
}
}
if ($last_cat_id && isset($level_array[$last_cat_id]))
{
//取出當(dāng)前結(jié)點(diǎn)的深度
$level = $level_array[$last_cat_id];
}
else
{
$level = 0;
}
}//end while,此時(shí)已完成非遞歸前序遍歷構(gòu)造樹的工作,其中$options已保存了從根結(jié)點(diǎn)開始的所有結(jié)點(diǎn)帶有分層性質(zhì)的數(shù)組
$cat_options[0] = $options;
}
else
{
$options = $cat_options[0];
}
//如果從0開始即取整個(gè)樹則直接返回不再處理.
if (!$spec_cat_id)
{
return $options;
}
//否則開始從指定結(jié)點(diǎn)截取,以下比較簡(jiǎn)單我還是稍微說說吧,要說就說幾個(gè)參數(shù)含義吧
/*
$spec_cat_id_level:截取結(jié)點(diǎn)的深度
$spec_cat_id_array:最終返回的以該結(jié)點(diǎn)為根結(jié)點(diǎn)的一棵商品分類樹
最終返回的數(shù)組是這樣排序的:按父親結(jié)點(diǎn)大小,按直接父親結(jié)點(diǎn),按同一父親結(jié)點(diǎn)這樣的先根遍歷,具個(gè)例子:
一級(jí)結(jié)點(diǎn)有1,5 二級(jí)結(jié)點(diǎn)有2,6,7 三級(jí)結(jié)點(diǎn)有8,9,如果1的直接孩子是2,6而2的直接孩子是8,9;另外
5的直接孩子是7那么最終的數(shù)組是這樣排列的1->2->8->9->6->5->7
*/
else
{
if (empty($options[$spec_cat_id]))
{
return array();
}
$spec_cat_id_level = $options[$spec_cat_id]['level'];
foreach ($options AS $key => $value)
{
if ($key != $spec_cat_id)
{
unset($options[$key]);
}
else
{
break;
}
}
$spec_cat_id_array = array();
foreach ($options AS $key => $value)
{
if (($spec_cat_id_level == $value['level'] && $value['cat_id'] != $spec_cat_id) ||
($spec_cat_id_level > $value['level']))
{
break;
}
else
{
$spec_cat_id_array[$key] = $value;
}
}
$cat_options[$spec_cat_id] = $spec_cat_id_array;
return $spec_cat_id_array;
}
}
- php實(shí)現(xiàn)無限級(jí)分類(遞歸方法)
- php 無限級(jí)分類,超級(jí)簡(jiǎn)單的無限級(jí)分類,支持輸出樹狀圖
- php實(shí)現(xiàn)無限級(jí)分類
- php實(shí)現(xiàn)無限級(jí)分類查詢(遞歸、非遞歸)
- ThinkPHP無限級(jí)分類原理實(shí)現(xiàn)留言與回復(fù)功能實(shí)例
- php+mysql實(shí)現(xiàn)無限級(jí)分類 | 樹型顯示分類關(guān)系
- ThinkPHP自動(dòng)填充實(shí)現(xiàn)無限級(jí)分類的方法
- php實(shí)現(xiàn)無限級(jí)分類實(shí)現(xiàn)代碼(遞歸方法)
- PHP實(shí)現(xiàn)遞歸無限級(jí)分類
- PHPTree——php快速生成無限級(jí)分類
相關(guān)文章
PHP調(diào)用Webservice實(shí)例代碼
NuSoap是PHP環(huán)境下的WebService編程工具,用于創(chuàng)建或調(diào)用WebService。2011-07-07
PHP ignore_user_abort函數(shù)詳細(xì)介紹和使用實(shí)例
這篇文章主要介紹了PHP ignore_user_abort函數(shù)詳細(xì)介紹和使用實(shí)例,本文包含2位作者的文章,相信可以幫你快速的理解ignore_user_abort函數(shù),需要的朋友可以參考下2014-07-07
PHP中include與require使用方法區(qū)別詳解
這篇文章詳細(xì)介紹了PHP中include與require使用方法的區(qū)別,有需要的朋友可以參考一下2013-10-10
php面向?qū)ο?一) 初窺(php面向?qū)ο蠡A(chǔ)介紹)
這篇文章主要介紹了php面向?qū)ο蟮囊恍┲R(shí),需要的朋友可以參考下2017-08-08
Cannot modify header information錯(cuò)誤解決方法
Warning: Cannot modify header information - headers already sent by出錯(cuò)的原因2008-10-10
Yii2框架實(shí)現(xiàn)注冊(cè)和登錄教程
這篇文章主要介紹了Yii2框架實(shí)現(xiàn)注冊(cè)和登錄教程的相關(guān)資料,需要的朋友可以參考下2016-09-09
盤點(diǎn)PHP和ASP.NET的10大對(duì)比!
本文主要針對(duì)開源 PHP 和非開源的 ASP.NET 在性能、成本、可擴(kuò)展性,技術(shù)支持和復(fù)雜性等方面進(jìn)行比較,感興趣的小伙伴們可以參考一下2015-12-12
使用游標(biāo)進(jìn)行PHP SQLSRV查詢的方法與注意事項(xiàng)
在 PHP 中使用 SQLSRV 查詢時(shí),如果查詢結(jié)果集較大,可以考慮使用游標(biāo)來提高查詢效率。使用游標(biāo)可以將查詢結(jié)果集分成多個(gè)小部分進(jìn)行處理,減輕服務(wù)器的負(fù)擔(dān),提高查詢性能2023-05-05
php使用curl簡(jiǎn)單抓取遠(yuǎn)程url的方法
這篇文章主要介紹了php使用curl簡(jiǎn)單抓取遠(yuǎn)程url的方法,涉及php操作curl的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
php求一個(gè)網(wǎng)段開始與結(jié)束IP地址的方法
這篇文章主要介紹了php求一個(gè)網(wǎng)段開始與結(jié)束IP地址的方法,涉及php字符串操作與進(jìn)制轉(zhuǎn)換的相關(guān)技巧,需要的朋友可以參考下2015-07-07

