表格展示无限级分类(PHP版)


Posted in PHP onAugust 21, 2012

TreeTable通过对单元格的行合并和列合并实现了无限层级也能较好的展示层级架构。
1.构建ID/PID/NAME的数组,后期可通过数据库生成的动态数据。Tree算法请点击

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

 2. 导入TreeTable类库。
import('@.ORG.Util.TableTree'); //Thinkphp导入方法

3. 生成TreeTable HTML代码
$treeTable->init($treearr); 
echo $treeTable->get_treetable();

注意:get_treetable()只生产表体部门,<TALBE></TABLE>请自行构建。
完整代码
<?php 
/** 
* File name: TreeTable.class.php 
* Author: run.gao 312854458@qq.com Date: 2012-07-24 23:22 GMT+8 
* Description: 通用的表格无限级分类 
* */ 
/** 
* 表格展示无限分类是将无线分类已表格的形式表现出来,更好的能体现出分类的所属关系 
* 使用方法: 
* 1. 实例化分类 
* $treeTable = new TreeTable(); 
* 2. 初始化分类,$treearr必须是一个多维数组且包含 id,parentid,name字段 
* $treeTable->init($treearr); 
* 3. 获取无限分类HTML代码 
* echo $treeTable->get_treetable(); 
* */ 
class TreeTable { 
/** 
* 生成树型结构所需要的2维数组 
* @var array 
*/ 
public $arr = array(); 
/** 
* 表格列数 
* @var int 
*/ 
public $columns = 0; 
/** 
* 表格行数 
* @var int 
*/ 
public $rows = 0; 
/** 
* 初始化TreeTable数据 
* @param array 2维数组 
* array( 
* 1 => array('id'=>'1','parentid'=>0,'name'=>'一级栏目一'), 
* 2 => array('id'=>'2','parentid'=>0,'name'=>'一级栏目二'), 
* 3 => array('id'=>'3','parentid'=>1,'name'=>'二级栏目一'), 
* 4 => array('id'=>'4','parentid'=>1,'name'=>'二级栏目二'), 
* 5 => array('id'=>'5','parentid'=>2,'name'=>'二级栏目三'), 
* 6 => array('id'=>'6','parentid'=>3,'name'=>'三级栏目一'), 
* 7 => array('id'=>'7','parentid'=>3,'name'=>'三级栏目二') 
* ) 
*/ 
public function init($arr=array()){ 
if(!is_array($arr)) return false; 
foreach ($arr as $k=>$v) { 
$this->arr[$v['id']] = $v; 
} 
foreach ($this->arr as $k => $v){ 
$this->arr[$k]['column'] = $this->get_level($v['id']); // Y轴位置 
$this->arr[$k]['arrchildid'] = $this->get_arrchildid($v['id']); // 所有子节点 
$this->arr[$k]['arrparentid'] = $this->get_arrparentid($v['id']); // 所有父节点 
$this->arr[$k]['child_bottom_num'] = $this->get_child_count($v['id']); // 所有底层元素节点 
} 
$this->columns = $this->get_columns(); // 总行数 
$this->rows = $this->get_rows(); // 总列数 
// 按照arrparentid和id号进行排序 
$this->sort_arr(); 
foreach ($this->arr as $k => $v){ 
$this->arr[$k]['row'] = $this->get_row_location($v['id']); // X轴位置 
$this->arr[$k]['rowspan'] = $v['child_bottom_num']; // 行合并数 
$this->arr[$k]['colspan'] = $v['child_bottom_num'] == 0 ? $this->columns - $v['column'] + 1 : 0; //列合并数 
} 
return $this->get_tree_arr(); 
} 
/** 
* 获取数组 
* */ 
public function get_tree_arr(){ 
return is_array($this->arr) ? $this->arr : false; 
} 
/** 
* 按arrparentid/id号依次重新排序数组 
* */ 
public function sort_arr(){ 
// 要进行排序的字段 
foreach ($this->arr as $k => $v){ 
$order_pid_arr[$k] = $v['arrparentid']; 
$order_iscost[] = $v['sort']; 
$order_id_arr[$k] = $v['id']; 
} 
// 先根据arrparentid排序,再根据排序,id号排序 
array_multisort( 
$order_pid_arr, SORT_ASC, SORT_STRING, 
$order_iscost, SORT_DESC, SORT_NUMERIC, 
$order_id_arr, SORT_ASC, SORT_NUMERIC, 
$this->arr); 
// 获取每一个节点层次 
for ($column = 1; $column <= $this->columns; $column++) { 
$row_level = 0; 
foreach ($this->arr as $key => $node){ 
if ($node['column'] == $column){ 
$row_level++; 
$this->arr[$key]['column_level'] = $row_level; 
} 
} 
} 
// 重新计算以ID作为键名 
foreach ($this->arr as $k=>$v) { 
$arr[$v['id']] = $v; 
} 
$this->arr = $arr; 
} 
/** 
* 得到父级数组 
* @param int 
* @return array 
*/ 
public function get_parent($myid){ 
$newarr = array(); 
if(!isset($this->arr[$myid])) return false; 
$pid = $this->arr[$myid]['parentid']; 
$pid = $this->arr[$pid]['parentid']; 
if(is_array($this->arr)){ 
foreach($this->arr as $id => $a){ 
if($a['parentid'] == $pid) $newarr[$id] = $a; 
} 
} 
return $newarr; 
} 
/** 
* 得到子级数组 
* @param int 
* @return array 
*/ 
public function get_child($myid){ 
$a = $newarr = array(); 
if(is_array($this->arr)){ 
foreach($this->arr as $id => $a){ 
if($a['parentid'] == $myid) $newarr[$id] = $a; 
} 
} 
return $newarr ? $newarr : false; 
} 
/** 
* 获取当前节点所在的层级 
* @param $myid 当前节点ID号 
* */ 
public function get_level($myid, $init = true){ 
static $level = 1; 
if($init) $level = 1; 
if ($this->arr[$myid]['parentid']) { 
$level++; 
$this->get_level($this->arr[$myid]['parentid'], false); 
} 
return $level; 
} 
/** 
* 获取当前节点所有底层节点(没有子节点的节点)的数量 
* @param $myid 节点ID号 
* @param $init 第一次加载将情况static变量 
* */ 
public function get_child_count($myid, $init = true){ 
static $count = 0; 
if($init) $count = 0; 
if(!$this->get_child($myid) && $init) return 0; 
if($childarr = $this->get_child($myid)){ 
foreach ($childarr as $v){ 
$this->get_child_count($v['id'], false); 
} 
}else{ 
$count++; 
} 
return $count; 
} 
/** 
* 获取节点所有子节点ID号 
* @param $catid 节点ID号 
* @param $init 第一次加载将情况static初始化 
* */ 
public function get_arrchildid($myid, $init = true) { 
static $childid; 
if($init) $childid = ''; 
if(!is_array($this->arr)) return false; 
foreach($this->arr as $id => $a){ 
if($a['parentid'] == $myid) { 
$childid = $childid ? $childid.','.$a['id'] : $a['id']; 
$this->get_arrchildid($a['id'], false); 
} 
} 
return $childid ; 
} 
/** 
* 获取该节点所有父节点ID号 
* @param $id 节点ID号 
* */ 
public function get_arrparentid($id, $arrparentid = '') { 
if(!is_array($this->arr)) return false; 
$parentid = $this->arr[$id]['parentid']; 
if($parentid > 0) $arrparentid = $arrparentid ? $parentid.','.$arrparentid : $parentid; 
if($parentid) $arrparentid = $this->get_arrparentid($parentid, $arrparentid); 
return $arrparentid; 
} 
/** 
* 获取节点所在地行定位 
* @param $myid 节点ID号 
*/ 
public function get_row_location($myid){ 
$nodearr = $this->arr; 
// 获取每一个节点所在行的位置 
foreach ($nodearr as $key => $node){ 
if($myid == $node['id']) { 
$node_row_count = 0; 
$arrparentid = explode(',', $node['arrparentid']); 
// 所有父节点小于当前节点层次的底层节点等于0的元素 
foreach ($arrparentid as $pid){ 
foreach ($nodearr as $node_row){ 
if($node_row['column'] == $nodearr[$pid]['column'] && $nodearr[$pid]['column_level'] > $node_row['column_level'] && $node_row['child_bottom_num'] == 0){ 
$node_row_count ++; 
} 
} 
} 
// 所有当前节点并且节点层次(rowid_level)小于当前节点层次的个数 
foreach ($nodearr as $node_row){ 
if($node['column'] == $node_row['column'] && $node_row['column_level'] < $node['column_level']){ 
$node_row_count += $node_row['child_bottom_num'] ? $node_row['child_bottom_num'] : 1; 
} 
} 
$node_row_count++; 
break; 
} 
} 
return $node_row_count; 
} 
/** 
* 获取表格的行数 
* */ 
public function get_rows(){ 
$row = 0; 
foreach ($this->arr as $key => $node){ 
if($node['child_bottom_num'] == 0){ 
$rows++; // 总行数 
} 
} 
return $rows; 
} 
/** 
* 获取表格的列数 
* */ 
public function get_columns(){ 
$columns = 0 ; 
foreach ($this->arr as $key => $node){ 
if($node['column'] > $columns){ 
$columns = $node['column']; // 总列数 
} 
} 
return $columns; 
} 
/** 
* 获取分类的表格展现形式(不包含表头) 
* */ 
public function get_treetable(){ 
$table_string = ''; 
for($row = 1; $row <= $this->rows; $row++){ 
$table_string .= "\r\t<tr>"; 
foreach ($this->arr as $v){ 
if($v['row'] == $row){ 
$rowspan = $v['rowspan'] ? "rowspan='{$v['rowspan']}'" : ''; 
$colspan = $v['colspan'] ? "colspan='{$v['colspan']}'" : ''; 
$table_string .= "\r\t\t<td {$rowspan} {$colspan}> 
{$v['name']} 
</td>"; 
} 
} 
$table_string .= "\r\t</tr>"; 
} 
return $table_string; 
} 
} 
?>
PHP 相关文章推荐
一棵php的类树(支持无限分类)
Oct 09 PHP
php项目打包方法
Feb 18 PHP
php中对xml读取的相关函数的介绍一
Jun 05 PHP
PHP学习之数组的定义和填充
Apr 17 PHP
配置php.ini实现PHP文件上传功能
Nov 27 PHP
php查询mssql出现乱码的解决方法
Dec 29 PHP
PHP积分兑换接口实例
Feb 09 PHP
ajax+php控制所有后台函数调用
Jul 15 PHP
WampServer搭建php环境时遇到的问题汇总
Jul 23 PHP
PHP面试常用算法(推荐)
Jul 22 PHP
php异步:在php中使用fsockopen curl实现类似异步处理的功能方法
Dec 10 PHP
Laravel5.5 数据库迁移:创建表与修改表示例
Oct 23 PHP
gd库图片下载类实现下载网页所有图片的php代码
Aug 20 #PHP
自己在做项目过程中学到的PHP知识收集
Aug 20 #PHP
用PHP+MySQL搭建聊天室功能实例代码
Aug 20 #PHP
PHP系列学习之日期函数使用介绍
Aug 18 #PHP
PHP中extract()函数的定义和用法
Aug 17 #PHP
Linux下实现PHP多进程的方法分享
Aug 16 #PHP
PHP基础知识回顾
Aug 16 #PHP
You might like
Terran剧情介绍
2020/03/14 星际争霸
phpMyAdmin 链接表的附加功能尚未激活的问题
2010/08/01 PHP
php 数组的指针操作实现代码
2011/02/08 PHP
PHP随手笔记整理之PHP脚本和JAVA连接mysql数据库
2015/11/25 PHP
PHP常见的6个错误提示及解决方法
2016/07/07 PHP
javascript小数计算出现近似值的解决办法
2010/02/06 Javascript
js 兼容多浏览器的回车和鼠标焦点事件代码(IE6/7/8,firefox,chrome)
2010/04/14 Javascript
用JavaScript计算在UTF-8下存储字符串占用字节数
2013/08/08 Javascript
JS简单实现文件上传实例代码(无需插件)
2013/11/15 Javascript
Node.js模拟浏览器文件上传示例
2014/03/26 Javascript
JavaScript charCodeAt方法入门实例(用于取得指定位置字符的Unicode编码)
2014/10/17 Javascript
基于javascript实现图片滑动效果
2016/05/07 Javascript
canvas的神奇用法
2017/02/03 Javascript
基于JS实现限时抢购倒计时间表代码
2017/05/09 Javascript
详解js类型判断
2018/05/22 Javascript
vue自定义底部导航栏Tabbar的实现代码
2018/09/03 Javascript
基于Node.js搭建hexo博客过程详解
2019/06/25 Javascript
JavaScript常用工具函数大全
2020/05/06 Javascript
vue-cli3配置favicon.ico和title的流程
2020/10/27 Javascript
[43:57]Liquid vs Mineski 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
python实现dnspod自动更新dns解析的方法
2014/02/14 Python
解决python2.7 查询mysql时出现中文乱码
2016/10/09 Python
Python中defaultdict与lambda表达式用法实例小结
2018/04/09 Python
python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序
2020/07/20 Python
Python、 Pycharm、Django安装详细教程(图文)
2019/04/12 Python
Python学习笔记之读取文件、OS模块、异常处理、with as语法示例
2019/06/04 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
2019/08/05 Python
python小项目之五子棋游戏
2019/12/26 Python
Python3自定义json逐层解析器代码
2020/05/11 Python
澳大利亚运动鞋商店:Platypus Shoes
2019/09/27 全球购物
民警群众路线教育实践活动对照检查材料
2014/10/04 职场文书
优秀教师事迹材料
2014/12/15 职场文书
学校中秋节活动总结
2015/03/23 职场文书
党支部季度考核意见
2015/06/02 职场文书
2015年教师国培感言
2015/08/01 职场文书
Nginx限流和黑名单配置
2022/05/20 Servers