在很多系统中会有层级体系,特别是在各种管本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】理系统的菜单、分类、部门等相关模块。一般【本文受版权保护】未经授权,禁止复制转载。而言,系统都会把这些对象保存在数据库中,【转载请注明来源】原创内容,盗版必究。并用一个parent_id字段去记录该对【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。象的父级对象。那么问题来了,当从数据库中【版权所有】唐霜 www.tangshuang.net【本文受版权保护】重新查出对象列表后,如何重新恢复其层级关转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。系呢?下面的这个函数可以帮到你:
本文作者:唐霜,转载请注明出处。【未经授权禁止转载】【未经授权禁止转载】<?php
/**
* 构建层级(树状)数组
* @param array $array 要进行处理的一维数组,经过该函数处理后,该数组自动转为树状数组
* @param string $pid 父级ID的字段名
* @return array|bool
*/
function array_tree(&$array, $pid = 'pid') {
// 子元素计数器
function array_children_count($array,$pid) {
$counter = array();
foreach($array as $item) {
$count = isset($counter[$item[$pid]]) ? $counter[$item[$pid]] : 0;
$count ++;
$counter[$item[$pid]] = $count;
}
return $counter;
}
// 把元素插入到对应的父元素children字段
function array_child_append($parent,$pid,$child) {
foreach($parent as &$item) {
if($item['id'] == $pid) {
if(!isset($item['children'])) $item['children'] = array();
$item['children'][] = $child;
}
}
return $parent;
}
// 开始程序
$counter = array_children_count($array,$pid);
// 如果顶级元素为0个,那么直接返回false
if($counter[0] == 0)
return false;
// 准备顶级元素
$tree = array();
// 位移
while(isset($counter[0]) && $counter[0] > 0) { // 如果顶级栏目的子元素计数器仍然大于0,那么仍然往下执行循环
$temp = array_shift($array);
if(isset($counter[$temp['id']]) && $counter[$temp['id']] > 0) { // 如果数组的第一个元素的子元素个数大于0,那么把该元素放置到数组的末端
array_push($array,$temp);
}
else { // 相反,如果该数组的第一个元素没有子元素,那么把该元素移动到其父元素的children字段中,同时,该元素从原数组中被删除
if($temp[$pid] == 0)
$tree[] = $temp;
else
$array = array_child_append($array,$temp[$pid],$temp);
}
$counter = array_children_count($array,$pid);
}
$array = $tree;
return $tree;
}
我来看下具体用法。本文作者:唐霜,转载请注明出处。
【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】它有两个参数,第一个是传入的要处理的数组本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。,注意,该数组必须是一维数组,而且所含字【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】段有规定:①必须是一维数组,②必须包含i【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。d字段,③必须包含$pid对应的字段,④【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net必须存在$pid为0的元素,也就是必须存【本文受版权保护】【本文首发于唐霜的博客】在顶级元素。处理结束时,那些没有追溯到$【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。pid=0的元素将被抛弃,只留下从$pi【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】d=0的顶级元素开始的树状结构,举个例子转载请注明出处:www.tangshuang.net【作者:唐霜】如下:
本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。$arr = array(
array('id' => 53,'pid' => 0),
array('id' => 64,'pid' => 53),
array('id' => 70,'pid' => 42)
);
array_tree($arr,'pid');
由于上面的例子中id=70这个元素的pi未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.netd=42,而id=42的元素并不存在,因【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。此在最终结果中id=70的这个元素会被抛未经授权,禁止复制转载。【原创不易,请尊重版权】弃。
著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】在使用过程中,array_tree处理后【本文首发于唐霜的博客】【转载请注明来源】,树状数组会存在一个排序问题。处理结果并未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。不会按照一定的规则进行升序或降序进行排列【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。,而是以逻辑处理过程中的内存顺序排列,虽【未经授权禁止转载】【未经授权禁止转载】然树状层级是正确的,但是同级元素的顺序是【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。不确定的。建议你通过array_orderby【本文受版权保护】函数,对处理后的结果进行排序处理。【作者:唐霜】
原创内容,盗版必究。【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。【本文受版权保护】【本文受版权保护】例子1:按从大到小规则排序的菜单原创内容,盗版必究。
原创内容,盗版必究。【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】【本文受版权保护】原创内容,盗版必究。$demo1 = array(
1 => array('id' => 1,'title' => 'title1','pid' => 0),
2 => array('id' => 2,'title' => 'title2','pid' => 1),
3 => array('id' => 3,'title' => 'title3','pid' => 1),
4 => array('id' => 4,'title' => 'title4','pid' => 2),
5 => array('id' => 5,'title' => 'title5','pid' => 2),
6 => array('id' => 6,'title' => 'title6','pid' => 0)
);
$demo1 = array_tree($demo1);// 或者直接使用array_tree($demo1);,无需返回值
array_orderby($demo1,'id','asc','children');
print_r($demo1);
例子2:菜单排列不规律,父菜单在后面原创内容,盗版必究。
本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。$demo2 = array(
1 => array('id' => 1,'title' => 'title1','parent_id' => 2),
2 => array('id' => 2,'title' => 'title2','parent_id' => 0),
3 => array('id' => 3,'title' => 'title3','parent_id' => 1),
4 => array('id' => 4,'title' => 'title4','parent_id' => 2),
5 => array('id' => 5,'title' => 'title5','parent_id' => 6),
6 => array('id' => 6,'title' => 'title6','parent_id' => 0)
);
array_tree($demo2,'parent_id');
array_orderby($demo2,'id','asc','children');
print_r($demo2);
在上面的例子中可以看出,无论一维数组中实【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。际的层级关系怎样复杂,该程序都能很好的进本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】行处理。注意,array_orderby【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】不是php的内置函数,你需要到上面链接文【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。章中获取。
【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。2016-02-03 10917


