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自动适应范围的分页代码
Aug 05 PHP
有关JSON以及JSON在PHP中的应用
Apr 09 PHP
用sql命令修改数据表中的一个字段为非空(not null)的语句
Jun 04 PHP
一些php技巧与注意事项分析
Feb 03 PHP
洪恩在线成语词典小偷程序php版
Apr 20 PHP
linux下使用crontab实现定时PHP计划任务失败的原因分析
Jul 05 PHP
PHP连接sql server 2005环境配置及问题解决
Aug 08 PHP
php进程间通讯实例分析
Jul 11 PHP
解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示
Nov 25 PHP
PHP解决中文乱码
Apr 28 PHP
php打开本地exe程序,js打开本地exe应用程序,并传递相关参数方法
Feb 06 PHP
PHP Redis扩展无法加载的问题解决方法
Aug 22 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 基于文件头的文件类型验证类函数
2012/05/01 PHP
PHP可变变量学习小结
2015/11/29 PHP
PHP-FPM 设置多pool及配置文件重写操作示例
2019/10/02 PHP
PHP实现新型冠状病毒疫情实时图的实例
2020/02/04 PHP
用js实现随机返回数组的一个元素
2007/08/13 Javascript
javascript面向对象之二 命名空间
2011/02/08 Javascript
50个比较实用jQuery代码段
2011/09/18 Javascript
JavaScript中的数组特性介绍
2014/12/30 Javascript
javascript实现滑动解锁功能
2014/12/31 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
实现React单页应用的方法详解
2016/08/02 Javascript
用js写的一个路由(简单实例)
2016/09/24 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
2017/06/08 jQuery
AngularJS实现select的ng-options功能示例
2017/07/12 Javascript
js学习总结_轮播图之渐隐渐现版(实例讲解)
2017/07/17 Javascript
JS监听事件的叠加和移除功能
2018/11/19 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
原生小程序封装跑马灯效果
2020/10/21 Javascript
python下函数参数的传递(参数带星号的说明)
2010/09/19 Python
Python二维码生成库qrcode安装和使用示例
2014/12/16 Python
python通过正则查找微博@(at)用户的方法
2015/03/13 Python
简单介绍Python中利用生成器实现的并发编程
2015/05/04 Python
Python selenium实现微博自动登录的示例代码
2018/05/16 Python
提升python处理速度原理及方法实例
2019/12/25 Python
python关于调用函数外的变量实例
2019/12/26 Python
python判断链表是否有环的实例代码
2020/01/31 Python
Python2手动安装更新pip过程实例解析
2020/07/16 Python
利用Python实现Json序列化库的方法步骤
2020/09/09 Python
英国奢侈品在线精品店:Hervia
2020/09/03 全球购物
产品设计开发计划书
2014/05/07 职场文书
大学生应聘求职信
2014/05/26 职场文书
公司授权委托书范文
2014/09/21 职场文书
村党支部书记个人对照材料汇报
2014/10/26 职场文书
本科毕业论文指导教师评语
2014/12/30 职场文书
幼儿园家长心得体会
2016/01/21 职场文书
《确定位置》教学反思
2016/02/18 职场文书