php无限分类, 支持输出树状图
<?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字段,存储父节点组合的的路径,就不用递归循环了。