当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP无限级分类实现程序

发布:smiling 来源: PHP粉丝网  添加日期:2014-08-28 14:41:56 浏览: 评论:0 

主要思路:首先看第三行和第四行,父类ID(PARENTID)的值是1,表示属于id=1这个类的子类,而一,二两行因为是一级分类,没有上级分类,所以父类ID(PARENTID)的值是0,表示初级分类,依次类推便实现了无限级分类,最终的效果是:

  1. ├一级分类A 
  2. ├─┴二级分类A 
  3. ├─┴二级分类B 
  4. ├一级分类B 

然后就是程序,这里以PHP作为描述语言,可以很方便的改成其他语言,因为原理相似,就是一个递归而已,代码如下:

  1. <?php 
  2. $dbhost = "localhost";   // 数据库主机名 
  3. $dbuser = "root";   // 数据库用户名 
  4. $dbpd = "123456";   // 数据库密码 
  5. $dbname = "test";   // 数据库名 
  6. mysql_connect($dbhost,$dbuser,$dbpd);       //连接主机 
  7. mysql_select_db($dbname);       //选择数据库 
  8. mysql_query("SET NAMES 'utf8'"); 
  9. display_tree("├",0); 
  10. function display_tree($tag,$classid) { 
  11.     $result = mysql_query(" 
  12.         SELECT * 
  13.         FROM ylmf_class 
  14.         WHERE parentid = '" . $classid . "' 
  15.         ;" 
  16.     ); 
  17.     while ($row = mysql_fetch_array($result)) { 
  18.         // 缩进显示节点名称 
  19.   echo $tag.$row['classname'] . "<br/>"
  20.         //再次调用这个函数显示子节点的子节点 
  21.   display_tree($tag."─┴",$row['id']); 
  22.     } 
  23. ?> 

在表格中显示TreeTable通过对单元格的行合并和列合并实现了无限层级也能较好的展示层级架构.

1.构建ID/PID/NAME的数组,后期可通过数据库生成的动态数据,代码如下:

  1. array
  2. * 1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'), 
  3. * 2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'), 
  4. * 3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'), 
  5. * 4 => array('id'=>'4','parentid'=>1,'name'=>'二级栏目二'), 
  6. * 5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目三'), 
  7. * 6 => array('id'=>'6','parentid'=>3,'name'=>'三级栏目一'), 
  8. * 7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目二'
  9. * ) 

2. 导入TreeTable类库,代码如下:

import('@.ORG.Util.TableTree'); //Thinkphp导入方法

3. 生成TreeTable HTML代码

$treeTable->init($treearr);

echo $treeTable->get_treetable();

注意:get_treetable()只生产表体部门,<TALBE></TABLE>请自行构建.

php完整代码如下:

  1. <?php 
  2. /** 
  3. * File name: TreeTable.class.php 
  4. * Author: run.gao 312854458@qq.com Date: 2012-07-24 23:22 GMT+8 
  5. * Description: 通用的表格无限级分类 
  6. * */ 
  7. /** 
  8. * 表格展示无限分类是将无线分类已表格的形式表现出来,更好的能体现出分类的所属关系 
  9. * 使用方法: 
  10. * 1. 实例化分类 
  11. * $treeTable = new TreeTable(); 
  12. * 2. 初始化分类,$treearr必须是一个多维数组且包含 id,parentid,name字段 
  13. * $treeTable->init($treearr); 
  14. * 3. 获取无限分类HTML代码 
  15. * echo $treeTable->get_treetable(); 
  16. * */ 
  17. class TreeTable { 
  18. /** 
  19. * 生成树型结构所需要的2维数组 
  20. * @var array 
  21. */ 
  22. public $arr = array(); 
  23. /** 
  24. * 表格列数 
  25. * @var int 
  26. */ 
  27. public $columns = 0; 
  28. /** 
  29. * 表格行数 
  30. * @var int 
  31. */ 
  32. public $rows = 0; 
  33. /** 
  34. * 初始化TreeTable数据 
  35. * @param array 2维数组 
  36. * array( 
  37. * 1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'), 
  38. * 2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'), 
  39. * 3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'), 
  40. * 4 => array('id'=>'4','parentid'=>1,'name'=>'二级栏目二'), 
  41. * 5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目三'), 
  42. * 6 => array('id'=>'6','parentid'=>3,'name'=>'三级栏目一'), 
  43. * 7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目二') 
  44. * ) 
  45. */ 
  46. public function init($arr=array()){ 
  47. if(!is_array($arr)) return false; 
  48. foreach ($arr as $k=>$v) { 
  49. $this->arr[$v['id']] = $v
  50. foreach ($this->arr as $k => $v){ 
  51. $this->arr[$k]['column'] = $this->get_level($v['id']); // Y轴位置 
  52. $this->arr[$k]['arrchildid'] = $this->get_arrchildid($v['id']); // 所有子节点 
  53. $this->arr[$k]['arrparentid'] = $this->get_arrparentid($v['id']); // 所有父节点 
  54. $this->arr[$k]['child_bottom_num'] = $this->get_child_count($v['id']); // 所有底层元素节点 
  55. $this->columns = $this->get_columns(); // 总行数 
  56. $this->rows = $this->get_rows(); // 总列数 
  57. // 按照arrparentid和id号进行排序 
  58. $this->sort_arr(); 
  59. foreach ($this->arr as $k => $v){ 
  60. $this->arr[$k]['row'] = $this->get_row_location($v['id']); // X轴位置 
  61. $this->arr[$k]['rowspan'] = $v['child_bottom_num']; // 行合并数 
  62. $this->arr[$k]['colspan'] = $v['child_bottom_num'] == 0 ? $this->columns - $v['column'] + 1 : 0; //列合并数 
  63. return $this->get_tree_arr(); 
  64. /** 
  65. * 获取数组 
  66. * */ 
  67. public function get_tree_arr(){ 
  68. return is_array($this->arr) ? $this->arr : false; 
  69. /** 
  70. * 按arrparentid/id号依次重新排序数组 
  71. * */ 
  72. public function sort_arr(){ 
  73. // 要进行排序的字段 
  74. foreach ($this->arr as $k => $v){ 
  75. $order_pid_arr[$k] = $v['arrparentid']; 
  76. $order_iscost[] = $v['sort']; 
  77. $order_id_arr[$k] = $v['id']; 
  78. // 先根据arrparentid排序,再根据排序,id号排序 
  79. array_multisort
  80. $order_pid_arr, SORT_ASC, SORT_STRING, 
  81. $order_iscost, SORT_DESC, SORT_NUMERIC, 
  82. $order_id_arr, SORT_ASC, SORT_NUMERIC, 
  83. $this->arr); 
  84. // 获取每一个节点层次 
  85. for ($column = 1; $column <= $this->columns; $column++) { 
  86. $row_level = 0; 
  87. foreach ($this->arr as $key => $node){ 
  88. if ($node['column'] == $column){ 
  89. $row_level++; 
  90. $this->arr[$key]['column_level'] = $row_level
  91. // 重新计算以ID作为键名 
  92. foreach ($this->arr as $k=>$v) { 
  93. $arr[$v['id']] = $v
  94. $this->arr = $arr
  95. /** 
  96. * 得到父级数组 
  97. * @param int 
  98. * @return array 
  99. */ 
  100. public function get_parent($myid){ 
  101. $newarr = array(); 
  102. if(!isset($this->arr[$myid])) return false; 
  103. $pid = $this->arr[$myid]['parentid']; 
  104. $pid = $this->arr[$pid]['parentid']; 
  105. if(is_array($this->arr)){ 
  106. foreach($this->arr as $id => $a){ 
  107. if($a['parentid'] == $pid$newarr[$id] = $a
  108. return $newarr
  109. /** 
  110. * 得到子级数组 
  111. * @param int 
  112. * @return array 
  113. */ 
  114. public function get_child($myid){ 
  115. $a = $newarr = array(); 
  116. if(is_array($this->arr)){ 
  117. foreach($this->arr as $id => $a){ 
  118. if($a['parentid'] == $myid$newarr[$id] = $a
  119. return $newarr ? $newarr : false; 
  120. /** 
  121. * 获取当前节点所在的层级 
  122. * @param $myid 当前节点ID号 
  123. * */ 
  124. public function get_level($myid$init = true){ 
  125. static $level = 1; 
  126. if($init$level = 1; 
  127. if ($this->arr[$myid]['parentid']) { 
  128. $level++; 
  129. $this->get_level($this->arr[$myid]['parentid'], false); 
  130. return $level
  131. /** 
  132. * 获取当前节点所有底层节点(没有子节点的节点)的数量 
  133. * @param $myid 节点ID号 
  134. * @param $init 第一次加载将情况static变量 
  135. * */ 
  136. public function get_child_count($myid$init = true){ 
  137. static $count = 0; 
  138. if($init$count = 0; 
  139. if(!$this->get_child($myid) && $initreturn 0; 
  140. if($childarr = $this->get_child($myid)){ 
  141. foreach ($childarr as $v){ 
  142. $this->get_child_count($v['id'], false); 
  143. }else
  144. $count++; 
  145. return $count
  146. /** 
  147. * 获取节点所有子节点ID号 
  148. * @param $catid 节点ID号 
  149. * @param $init 第一次加载将情况static初始化 
  150. * */ 
  151. public function get_arrchildid($myid$init = true) { 
  152. static $childid
  153. if($init$childid = ''
  154. if(!is_array($this->arr)) return false; 
  155. foreach($this->arr as $id => $a){ 
  156. if($a['parentid'] == $myid) { 
  157. $childid = $childid ? $childid.','.$a['id'] : $a['id']; 
  158. $this->get_arrchildid($a['id'], false); 
  159. return $childid ; 
  160. /** 
  161. * 获取该节点所有父节点ID号 
  162. * @param $id 节点ID号 
  163. * */ 
  164. public function get_arrparentid($id$arrparentid = '') { 
  165. if(!is_array($this->arr)) return false; 
  166. $parentid = $this->arr[$id]['parentid']; 
  167. if($parentid > 0) $arrparentid = $arrparentid ? $parentid.','.$arrparentid : $parentid
  168. if($parentid$arrparentid = $this->get_arrparentid($parentid$arrparentid); 
  169. return $arrparentid
  170. /** 
  171. * 获取节点所在地行定位 
  172. * @param $myid 节点ID号 
  173. */ 
  174. public function get_row_location($myid){ 
  175. $nodearr = $this->arr; 
  176. // 获取每一个节点所在行的位置 
  177. foreach ($nodearr as $key => $node){ 
  178. if($myid == $node['id']) { 
  179. $node_row_count = 0; 
  180. $arrparentid = explode(','$node['arrparentid']); 
  181. // 所有父节点小于当前节点层次的底层节点等于0的元素 
  182. foreach ($arrparentid as $pid){ 
  183. foreach ($nodearr as $node_row){ 
  184. if($node_row['column'] == $nodearr[$pid]['column'] && $nodearr[$pid]['column_level'] > $node_row['column_level'] && $node_row['child_bottom_num'] == 0){ 
  185. $node_row_count ++; 
  186. // 所有当前节点并且节点层次(rowid_level)小于当前节点层次的个数 
  187. foreach ($nodearr as $node_row){ 
  188. if($node['column'] == $node_row['column'] && $node_row['column_level'] < $node['column_level']){ 
  189. $node_row_count += $node_row['child_bottom_num'] ? $node_row['child_bottom_num'] : 1; 
  190. $node_row_count++; 
  191. break
  192. return $node_row_count
  193. /** 
  194. * 获取表格的行数 
  195. * */ 
  196. public function get_rows(){ 
  197. $row = 0; 
  198. foreach ($this->arr as $key => $node){ 
  199. if($node['child_bottom_num'] == 0){ 
  200. $rows++; // 总行数 
  201. return $rows
  202. /** 
  203. * 获取表格的列数 
  204. * */ 
  205. public function get_columns(){ 
  206. $columns = 0 ; 
  207. foreach ($this->arr as $key => $node){ 
  208. if($node['column'] > $columns){ 
  209. $columns = $node['column']; // 总列数 
  210. return $columns
  211. /** 
  212. * 获取分类的表格展现形式(不包含表头) 
  213. * */ 
  214. public function get_treetable(){ 
  215. $table_string = ''
  216. for($row = 1; $row <= $this->rows; $row++){ 
  217. $table_string .= "rt<tr>"
  218. foreach ($this->arr as $v){ 
  219. if($v['row'] == $row){ 
  220. $rowspan = $v['rowspan'] ? "rowspan='{$v['rowspan']}'" : ''
  221. $colspan = $v['colspan'] ? "colspan='{$v['colspan']}'" : ''
  222. $table_string .= "rtt<td {$rowspan} {$colspan}> 
  223. {$v['name']}//开源代码phpfensi.com 
  224. </td>"; 
  225. $table_string .= "rt</tr>"
  226. return $table_string

Tags: php无限级分类 php分类实例

分享到: