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控制用户的浏览器--ob*函数的使用说明
Mar 16 PHP
相对路径转化成绝对路径
Apr 10 PHP
有关PHP中MVC的开发经验分享
May 17 PHP
微信支付开发教程(一)微信支付URL配置
May 28 PHP
在win7中搭建Linux+PHP 开发环境
Oct 08 PHP
微信access_token的获取开发示例
Apr 16 PHP
php中JSON的使用方法
Apr 30 PHP
php上传图片类及用法示例
May 11 PHP
php头像上传预览实例代码
May 02 PHP
PHP与Perl之间知识点区别整理
Mar 19 PHP
Laravel 登录后清空COOKIE的操作方法
Oct 14 PHP
微信小程序发送订阅消息的方法(php 为例)
Oct 30 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 json_encode奇怪问题说明
2011/09/27 PHP
利用PHP将部分内容用星号替换
2020/04/21 PHP
详解php比较操作符的安全问题
2015/12/03 PHP
PHP自定义函数获取URL中一级域名的方法
2016/08/23 PHP
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
js上传图片及预览功能实例分析
2015/04/24 Javascript
javascript图片滑动效果实现
2021/01/28 Javascript
基于javascript实现图片预加载
2016/01/05 Javascript
js点击文本框弹出可选择的checkbox复选框
2016/02/03 Javascript
BootStrap智能表单实战系列(十一)级联下拉的支持
2016/06/13 Javascript
JS获取年月日时分秒的方法分析
2016/11/28 Javascript
手机软键盘弹出时影响布局的解决方法
2016/12/15 Javascript
js实现本地图片文件拖拽效果
2017/07/18 Javascript
vue项目中的webpack-dev-sever配置方法
2017/12/14 Javascript
Vue修改mint-ui默认样式的方法
2018/02/03 Javascript
vue 子组件向父组件传值方法
2018/02/26 Javascript
vue 实现走马灯效果
2019/10/28 Javascript
从表单校验看JavaScript策略模式的使用详解
2020/10/17 Javascript
[03:30]DOTA2完美“圣”典精彩集锦
2016/12/27 DOTA
Python ZipFile模块详解
2013/11/01 Python
用Python的pandas框架操作Excel文件中的数据教程
2015/03/31 Python
Python发送以整个文件夹的内容为附件的邮件的教程
2015/05/06 Python
python之matplotlib学习绘制动态更新图实例代码
2018/01/23 Python
python对excel文档去重及求和的实例
2018/04/18 Python
Python查找两个有序列表中位数的方法【基于归并算法】
2018/04/20 Python
python去除文件中重复的行实例
2018/06/29 Python
python实现一组典型数据格式转换
2018/12/15 Python
Python反爬虫伪装浏览器进行爬虫
2020/02/28 Python
Debenhams百货英国官方网站:Debenhams UK
2016/07/12 全球购物
英国最受欢迎的价格比较网站之一:MoneySuperMarket
2018/12/19 全球购物
Tom Dixon官网:英国照明及家具设计和制造公司
2019/03/01 全球购物
大学本科毕业生的自我鉴定
2013/11/26 职场文书
人身损害赔偿协议书格式
2014/11/01 职场文书
经理岗位职责范本
2015/04/15 职场文书
海上钢琴师观后感
2015/06/03 职场文书
Python 居然可以在 Excel 中画画你知道吗
2022/02/15 Python