php 无限级分类 带上自身,php 无限级分类学习参考之对ecshop无限级分类的解析 带详细注释...

对ecshop无限级分类的解析,认真分析后发现真的其算法还是比较精典的其实并不难理解,有举例方便大家理解。

function cat_options($spec_cat_id, $arr)

{

static $cat_options = array();

if (isset($cat_options[$spec_cat_id]))

{

return $cat_options[$spec_cat_id];

}

/*

初始化关键参数:

$level:当前子节点深度

$last_cat_id:当前父节点ID

$options:带有缩进级别的数组

$cat_id_array:沿同一路径的父节点依次进驻

$level_array:该节点的子节点深度,也是依次进驻

*/

if (!isset($cat_options[0]))

{

$level = $last_cat_id = 0;

$options = $cat_id_array = $level_array = array();

while (!empty($arr))//如果还有待构造的节点则继续遍历

{

foreach ($arr AS $key => $value)

{

$cat_id = $value['cat_id'];

//一级分类结点

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;//下层结点的父亲结点

$cat_id_array = array($cat_id);

$level_array[$last_cat_id] = ++$level;

continue;

}

//当前结点的父亲结点ID等于它的上一级结点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]);//遍历过了就不再遍历

//如果当前结点有孩子则当前结点要进驻,但不再遍历;反之不进驻也不再遍历

if ($value['has_children'] > 0)

{

if (end($cat_id_array) != $last_cat_id)

{

$cat_id_array[] = $last_cat_id;

}

$last_cat_id = $cat_id;//当现结点做为下一级结点的新的父亲结点

$cat_id_array[] = $cat_id;//进驻

$level_array[$last_cat_id] = ++$level;//当前结点的下一级结点深度

}

}

elseif ($value['parent_id'] > $last_cat_id)

{//如果当前结点父亲深度大于目前父亲结点的深度则进行下一轮循环

break;

}

}//endforeach

$count = count($cat_id_array);

if ($count > 1)

{

//取出最后进驻的父亲节点作为当前父亲节点

$last_cat_id = array_pop($cat_id_array);

}

elseif ($count == 1)

{

if ($last_cat_id != end($cat_id_array))

{

//进驻的父亲结点只有一个时并且没有作为当前父亲节点时把它取出

$last_cat_id = end($cat_id_array);

}

else

{ //否则最后取出的父亲结点一定是一级分类结点

$level = 0;

$last_cat_id = 0;

$cat_id_array = array();

continue;

}

}

if ($last_cat_id && isset($level_array[$last_cat_id]))

{

//取出当前结点的深度

$level = $level_array[$last_cat_id];

}

else

{

$level = 0;

}

}//end while,此时已完成非递归前序遍历构造树的工作,其中$options已保存了从根结点开始的所有结点带有分层性质的数组

$cat_options[0] = $options;

}

else

{

$options = $cat_options[0];

}

//如果从0开始即取整个树则直接返回不再处理.

if (!$spec_cat_id)

{

return $options;

}

//否则开始从指定结点截取,以下比较简单我还是稍微说说吧,要说就说几个参数含义吧

/*

$spec_cat_id_level:截取结点的深度

$spec_cat_id_array:最终返回的以该结点为根结点的一棵商品分类树

最终返回的数组是这样排序的:按父亲结点大小,按直接父亲结点,按同一父亲结点这样的先根遍历,具个例子:

一级结点有1,5 二级结点有2,6,7 三级结点有8,9,如果1的直接孩子是2,6而2的直接孩子是8,9;另外

5的直接孩子是7那么最终的数组是这样排列的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;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值