<?php
002 |
/** |
003 |
* 通用的树型类,可以生成任何树型结构 |
004 |
*/ |
005 |
class tree |
006 |
{ |
007 |
/** |
008 |
* 生成树型结构所需要的2维数组 |
009 |
* @var array |
010 |
*/ |
011 |
var $arr = array(); |
012 |
013 |
/** |
014 |
* 生成树型结构所需修饰符号,可以换成图片 |
015 |
* @var array |
016 |
*/ |
017 |
var $icon = array('│','├','└'); |
018 |
019 |
/** |
020 |
* @access private |
021 |
*/ |
022 |
var $ret = ''; |
023 |
024 |
/** |
025 |
* 构造函数,初始化类 |
026 |
* @param array 2维数组,例如: |
027 |
* array( |
028 |
* 1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'), |
029 |
* 2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'), |
030 |
* 3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'), |
031 |
* 4 => array('id'=>'4','parentid'=>1,'name'=>'二级栏目二'), |
032 |
* 5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目三'), |
033 |
* 6 => array('id'=>'6','parentid'=>3,'name'=>'三级栏目一'), |
034 |
* 7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目二') |
035 |
* ) |
036 |
*/ |
037 |
function tree($arr=array()) |
038 |
{ |
039 |
$this->arr = $arr; |
040 |
$this->ret = ''; |
041 |
return is_array($arr); |
042 |
} |
043 |
044 |
/** |
045 |
* 得到父级数组 |
046 |
* @param int |
047 |
* @return array |
048 |
*/ |
049 |
function get_parent($myid) |
050 |
{ |
051 |
$newarr = array(); |
052 |
if(!isset($this->arr[$myid])) return false; |
053 |
$pid = $this->arr[$myid]['parentid']; |
054 |
$pid = $this->arr[$pid]['parentid']; |
055 |
if(is_array($this->arr)) |
056 |
{ |
057 |
foreach($this->arr as $id => $a) |
058 |
{ |
059 |
if($a['parentid'] == $pid) $newarr[$id] = $a; |
060 |
} |
061 |
} |
062 |
return $newarr; |
063 |
} |
064 |
065 |
/** |
066 |
* 得到子级数组 |
067 |
* @param int |
068 |
* @return array |
069 |
*/ |
070 |
function get_child($myid) |
071 |
{ |
072 |
$a = $newarr = array(); |
073 |
if(is_array($this->arr)) |
074 |
{ |
075 |
foreach($this->arr as $id => $a) |
076 |
{ |
077 |
if($a['parentid'] == $myid) $newarr[$id] = $a; |
078 |
} |
079 |
} |
080 |
return $newarr ? $newarr : false; |
081 |
} |
082 |
083 |
/** |
084 |
* 得到当前位置数组 |
085 |
* @param int |
086 |
* @return array |
087 |
*/ |
088 |
function get_pos($myid,&$newarr) |
089 |
{ |
090 |
$a = array(); |
091 |
if(!isset($this->arr[$myid])) return false; |
092 |
$newarr[] = $this->arr[$myid]; |
093 |
$pid = $this->arr[$myid]['parentid']; |
094 |
if(isset($this->arr[$pid])) |
095 |
{ |
096 |
$this->get_pos($pid,$newarr); |
097 |
} |
098 |
if(is_array($newarr)) |
099 |
{ |
100 |
krsort($newarr); |
101 |
foreach($newarr as $v) |
102 |
{ |
103 |
$a[$v['id']] = $v; |
104 |
} |
105 |
} |
106 |
return $a; |
107 |
} |
108 |
109 |
110 |
/** |
111 |
* ------------------------------------- |
112 |
* 得到树型结构 |
113 |
* ------------------------------------- |
114 |
* @author Midnight(杨云洲), yangyunzhou@foxmail.com |
115 |
* @param $myid 表示获得这个ID下的所有子级 |
116 |
* @param $str 生成树形结构基本代码, 例如: "<option value=\$id \$select>\$spacer\$name</option>" |
117 |
* @param $sid 被选中的ID, 比如在做树形下拉框的时候需要用到 |
118 |
* @param $adds |
119 |
* @param $str_group |
120 |
* @return unknown_type |
121 |
*/ |
122 |
function get_tree($myid, $str, $sid = 0, $adds = '', $str_group = '') |
123 |
{ |
124 |
$number=1; |
125 |
$child = $this->get_child($myid); |
126 |
if(is_array($child)) |
127 |
{ |
128 |
$total = count($child); |
129 |
foreach($child as $id=>$a) |
130 |
{ |
131 |
$j=$k=''; |
132 |
if($number==$total) |
133 |
{ |
134 |
$j .= $this->icon[2]; |
135 |
} |
136 |
else |
137 |
{ |
138 |
$j .= $this->icon[1]; |
139 |
$k = $adds ? $this->icon[0] : ''; |
140 |
} |
141 |
$spacer = $adds ? $adds.$j : ''; |
142 |
$selected = $id==$sid ? 'selected' : ''; |
143 |
@extract($a); |
144 |
$parentid == 0 && $str_group ? eval("\$nstr = \"$str_group\";") : eval("\$nstr = \"$str\";"); |
145 |
$this->ret .= $nstr; |
146 |
$this->get_tree($id, $str, $sid, $adds.$k.' ',$str_group); |
147 |
$number++; |
148 |
} |
149 |
} |
150 |
return $this->ret; |
151 |
} |
152 |
/** |
153 |
* 同上一方法类似,但允许多选 |
154 |
*/ |
155 |
function get_tree_multi($myid, $str, $sid = 0, $adds = '') |
156 |
{ |
157 |
$number=1; |
158 |
$child = $this->get_child($myid); |
159 |
if(is_array($child)) |
160 |
{ |
161 |
$total = count($child); |
162 |
foreach($child as $id=>$a) |
163 |
{ |
164 |
$j=$k=''; |
165 |
if($number==$total) |
166 |
{ |
167 |
$j .= $this->icon[2]; |
168 |
} |
169 |
else |
170 |
{ |
171 |
$j .= $this->icon[1]; |
172 |
$k = $adds ? $this->icon[0] : ''; |
173 |
} |
174 |
$spacer = $adds ? $adds.$j : ''; |
175 |
176 |
$selected = $this->have($sid,$id) ? 'selected' : ''; |
177 |
//echo $sid.'=>'.$id.' : '.$selected.' . <br/>'; |
178 |
@extract($a); |
179 |
eval("\$nstr = \"$str\";"); |
180 |
$this->ret .= $nstr; |
181 |
$this->get_tree_multi($id, $str, $sid, $adds.$k.' '); |
182 |
$number++; |
183 |
} |
184 |
} |
185 |
return $this->ret; |
186 |
} |
187 |
188 |
function have($list,$item){ |
189 |
return(strpos(',,'.$list.',',','.$item.',')); |
190 |
} |
191 |
} |
192 |
?> |
[图片] 12.jpg

[图片] 22.jpg

注意:其实可以添加一个新的path字段,存储父节点组合的的路径,就不用递归循环了。