2款PHP无限级分类实例代码

这篇文章主要介绍了2款PHP无限级分类实例代码,需要的朋友可以参考下

本文章总结了两款PHP无限级分类实现程序代码,有需要学习的朋友可参考一下。

主要思路:首先看第三行和第四行,父类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. }
  24. ?>

在表格中显示

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

1.构建ID/PID/NAME的数组,后期可通过数据库生成的动态数据。Tree算法请点击

  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>请自行构建。

完整代码:

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

希望本文所述对大家学习php程序设计有所帮助。