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上传图片、删除图片实现代码
May 12 PHP
PHP魔术引号所带来的安全问题分析
Jul 15 PHP
php匹配字符中链接地址的方法
Dec 22 PHP
php使用Cookie实现和用户会话的方法
Jan 21 PHP
php中Snoopy类用法实例
Jun 19 PHP
PHP实现动态执行代码的方法
Mar 25 PHP
基于PHP微信红包的算法探讨
Jul 21 PHP
PHP简单判断iPhone、iPad、Android及PC设备的方法
Oct 11 PHP
php使用curl实现简单模拟提交表单功能
May 15 PHP
php基于session锁防止阻塞请求的方法分析
Aug 07 PHP
Laravel框架实现的记录SQL日志功能示例
Jun 19 PHP
php支付宝APP支付功能
Jul 29 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 xml留言板 xml存储数据的简单例子
2009/08/24 PHP
一个比较简单的PHP 分页分组类
2009/12/10 PHP
php修改时间格式的代码
2011/05/29 PHP
在PHP模板引擎smarty生成随机数的方法和math函数详解
2014/04/24 PHP
Yii框架使用魔术方法实现跨文件调用功能示例
2017/05/20 PHP
Ajax+Jpgraph实现的动态折线图功能示例
2019/02/11 PHP
在TP5数据库中四个字段实现无限分类的示例
2019/10/18 PHP
laravel 解决Validator使用中出现的问题
2019/10/25 PHP
用脚本调用样式的几种方法
2006/12/09 Javascript
JavaScript 开发规范要求(图文并茂)
2010/06/11 Javascript
TinyMCE 新增本地图片上传功能
2010/11/05 Javascript
autoPlay 基于jquery的图片自动播放效果
2011/12/07 Javascript
js中eval详解
2012/03/30 Javascript
javascript去掉前后空格的实例
2013/11/07 Javascript
js实现商品抛物线加入购物车特效
2020/11/18 Javascript
Javascript简写条件语句(推荐)
2016/06/12 Javascript
基于WebUploader的文件上传js插件
2016/08/19 Javascript
jquery实现简单实用的轮播器
2017/05/23 jQuery
jQuery实现图片上传预览效果功能完整实例【测试可用】
2018/05/28 jQuery
Nuxt升级2.0.0时出现的问题(小结)
2018/10/08 Javascript
jquery弹窗时禁止body滚动条滚动的例子
2019/09/21 jQuery
JS实现iframe中子父页面跨域通讯的方法分析
2020/03/10 Javascript
Python实现破解猜数游戏算法示例
2017/09/25 Python
python 利用百度API识别图片文字(多线程版)
2020/12/14 Python
怎样在 Applet 中建立自己的菜单(MenuBar/Menu)?
2012/06/20 面试题
大学毕业生个人自荐信范文
2014/01/08 职场文书
初中语文教学反思
2014/02/02 职场文书
商场促销活动方案
2014/02/08 职场文书
药品采购员岗位职责
2014/02/08 职场文书
电子商务专业求职信
2014/03/08 职场文书
工程采购员岗位职责
2014/03/09 职场文书
港澳通行证委托书怎么写
2014/08/02 职场文书
乡镇遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
2014年生产管理工作总结
2014/12/23 职场文书
2015年健康教育工作总结
2015/04/10 职场文书
电力工程合作意向书
2015/05/11 职场文书