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 !function_exists("T7FC56270E7A70FA81A5935B72EACBE29"))代码解密
Jan 07 PHP
php读取EXCEL文件 php excelreader读取excel文件
Dec 06 PHP
PHP笔记之:日期函数的使用介绍
Apr 24 PHP
PHP 清空varnish 缓存的详解(包括指定站点下的)
Jun 20 PHP
php防注入及开发安全详细解析
Aug 09 PHP
php实现的css文件背景图片下载器代码
Nov 11 PHP
帝国cms目录结构分享
Jul 06 PHP
简单谈谈PHP中strlen 函数
Feb 27 PHP
PHP Smarty模版简单使用方法
Mar 30 PHP
php微信公众平台开发(三)订阅事件处理
Dec 06 PHP
PHP 爬取网页的主要方法
Jul 13 PHP
PHP实现简单注册登录系统
Dec 28 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初学入门
2006/11/19 PHP
PHP根据IP判断地区名信息的示例代码
2014/03/03 PHP
ThinkPHP多表联合查询的常用方法
2020/03/24 PHP
CI框架集成Smarty的方法分析
2016/05/17 PHP
浅谈PHP安全防护之Web攻击
2017/01/03 PHP
PHP asXML()函数讲解
2019/02/03 PHP
使用jQuery实现dropdownlist的联动效果(sharepoint 2007)
2011/03/30 Javascript
JS生成随机字符串的多种方法
2014/06/10 Javascript
javascript修改图片src的方法
2015/01/27 Javascript
javascript如何写热点图
2015/12/08 Javascript
Boostrap模态窗口的学习小结
2016/03/28 Javascript
js利用for in循环获取 一个对象的所有属性以及值的实例
2017/03/30 Javascript
基于JavaScript表单脚本(详解)
2017/10/18 Javascript
vue中使用refs定位dom出现undefined的解决方法
2017/12/21 Javascript
SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法
2018/01/09 Javascript
详解React之父子组件传递和其它一些要点
2018/06/25 Javascript
小程序清理本地缓存的方法
2018/08/17 Javascript
JS实现“全选”和"全不选"功能代码实例
2020/02/06 Javascript
解决python删除文件的权限错误问题
2018/04/24 Python
如何使用Python的Requests包实现模拟登陆
2018/04/27 Python
python遍历小写英文字母的方法
2019/01/02 Python
Python基本数据结构与用法详解【列表、元组、集合、字典】
2019/03/23 Python
Python PyQt5整理介绍
2020/04/01 Python
使用python爬取抖音app视频的实例代码
2020/12/01 Python
使用iframe+postMessage实现页面跨域通信的示例代码
2020/01/14 HTML / CSS
python+selenium小米商城红米K40手机自动抢购的示例代码
2021/03/24 Python
无故旷工检讨书
2014/01/26 职场文书
幼儿教师研修感言
2014/02/12 职场文书
环保建议书
2014/03/12 职场文书
产品售后服务承诺书
2014/05/21 职场文书
开展党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
爱心捐款感谢信
2015/01/20 职场文书
寒假社会实践个人总结
2015/03/06 职场文书
女人创业励志语录,句句蕴含能量,激发你的潜能
2019/08/20 职场文书
Ruby使用Mysql2连接操作MySQL
2022/04/19 Ruby
ipad隐藏软件app图标方法
2022/04/19 数码科技