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


Posted in PHP onMarch 23, 2010
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; 
} 
}
PHP 相关文章推荐
php做下载文件的实现代码及文件名中乱码解决方法
Feb 03 PHP
php安全配置 如何配置使其更安全
Dec 16 PHP
php图片加中文水印实现代码分享
Oct 31 PHP
PHP微框架Dispatch简介
Jun 12 PHP
php获取网页请求状态程序示例
Jun 17 PHP
PHP Opcache安装和配置方法介绍
May 28 PHP
php使用pear_smtp发送邮件
Apr 15 PHP
Laravel 5.3 学习笔记之 配置
Aug 28 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
Dec 26 PHP
PHP实现的超长文本分页显示功能示例
Jun 04 PHP
PHP实现 APP端微信支付功能
Jun 22 PHP
imagettftext() 失效,不起作用
Mar 09 PHP
PHP提取数据库内容中的图片地址并循环输出
Mar 21 #PHP
mysql From_unixtime及UNIX_TIMESTAMP及DATE_FORMAT日期函数
Mar 21 #PHP
PHP中10个不常见却非常有用的函数
Mar 21 #PHP
初次接触php抽象工厂模式(Elgg)
Mar 21 #PHP
PHP5与MySQL数据库操作常用代码 收集
Mar 21 #PHP
ajax+php打造进度条 readyState各状态
Mar 20 #PHP
elgg 获取文件图标地址的方法
Mar 20 #PHP
You might like
php图片的二进制转换实现方法
2014/12/15 PHP
smarty缓存用法分析
2014/12/16 PHP
微信利用PHP创建自定义菜单的方法
2016/08/01 PHP
php生成毫秒时间戳的实例讲解
2017/09/22 PHP
thinkPHP框架实现的无限回复评论功能示例
2018/06/09 PHP
thinkphp3.2同时连接两个数据库的简单方法
2019/08/13 PHP
thinkphp3.2框架中where条件查询用法总结
2019/08/13 PHP
javascript实现验证IP地址等相关信息代码
2015/05/10 Javascript
Javascript中Array用法实例分析
2015/06/13 Javascript
基于JavaScript实现TAB标签效果
2016/01/12 Javascript
JavaScript设计模式之命令模式实例分析
2019/01/16 Javascript
vue下canvas裁剪图片实例讲解
2020/04/16 Javascript
在vue项目中利用popstate处理页面返回的操作介绍
2020/08/06 Javascript
前端vue如何使用高德地图
2020/11/05 Javascript
python函数局部变量用法实例分析
2015/08/04 Python
Python基于回溯法子集树模板解决最佳作业调度问题示例
2017/09/08 Python
Python 实现网页自动截图的示例讲解
2018/05/17 Python
Python使用字典的嵌套功能详解
2019/02/27 Python
Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法
2019/12/17 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
Python调用系统命令os.system()和os.popen()的实现
2020/12/31 Python
美国大尺码女装零售商:TORRID
2016/10/01 全球购物
美国受欢迎的女性牛仔裤品牌:DL1961
2016/11/12 全球购物
美体小铺瑞典官方网站:The Body Shop瑞典
2018/01/27 全球购物
TripAdvisor斯洛伐克:阅读评论、比较价格和酒店预订
2018/04/25 全球购物
香港连卡佛百货官网:Lane Crawford
2019/09/04 全球购物
Unix如何在一行中运行多个命令
2015/05/29 面试题
电子工程专业毕业生求职信
2014/03/14 职场文书
市场拓展计划书
2014/05/03 职场文书
说明书格式及范文
2014/05/07 职场文书
项目委托协议书(最新)
2014/09/13 职场文书
党员年度个人总结
2015/02/14 职场文书
学子宴致辞大全
2015/07/27 职场文书
采购部年度工作总结
2015/08/13 职场文书
pytorch 中autograd.grad()函数的用法说明
2021/05/12 Python
python munch库的使用解析
2021/05/25 Python