表格展示无限级分类(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网页后退不再出现过期
Mar 08 PHP
php中0,null,empty,空,false,字符串关系的详细介绍
Jun 20 PHP
PHP常用的缓存技术汇总
May 05 PHP
php短网址和数字之间相互转换的方法
Mar 13 PHP
PHP多文件上传实例
Jul 09 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
Aug 16 PHP
Zend Framework教程之Application用法实例详解
Mar 14 PHP
Linux php 中文乱码的快速解决方法
May 13 PHP
php安装ssh2扩展的方法【Linux平台】
Jul 20 PHP
Yii2中使用asset压缩js,css文件的方法
Nov 24 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
PHP 枚举类型的管理与设计知识点总结
Feb 13 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
php下检测字符串是否是utf8编码的代码
2008/06/28 PHP
使用PHP实现二分查找算法代码分享
2011/06/24 PHP
PHP yii实现model添加默认值的方法(两种方法)
2016/11/10 PHP
PHP正则匹配操作简单示例【preg_match_all应用】
2017/07/10 PHP
浅谈PHP array_search 和 in_array 函数效率问题
2019/10/15 PHP
jQuery使用手册之三 CSS操作
2007/03/24 Javascript
jquery学习笔记 用jquery实现无刷新登录
2011/08/08 Javascript
checkbox全选所涉及到的知识点介绍
2013/12/31 Javascript
解决用jquery load加载页面到div时,不执行页面js的问题
2014/02/22 Javascript
javascript arguments使用示例
2014/12/16 Javascript
JavaScript实现动画打开半透明提示层的方法
2015/04/21 Javascript
JavaScript验证Email(3种方法)
2015/09/21 Javascript
js仿微博实现统计字符和本地存储功能
2015/12/22 Javascript
jQuery实现的无缝广告图片左右滚动功能详解
2016/12/24 Javascript
JS实现列表页面隔行变色效果
2017/03/25 Javascript
JS表单传值和URL编码转换
2018/03/03 Javascript
深入理解Vue父子组件生命周期执行顺序及钩子函数
2018/08/12 Javascript
vue移动端下拉刷新和上拉加载的实现代码
2018/09/08 Javascript
vscode配置vue下的es6规范自动格式化详解
2019/03/20 Javascript
vue自定义指令directive的使用方法
2019/04/07 Javascript
vue axios封装及API统一管理的方法
2019/04/18 Javascript
原生JS实现列表内容自动向上滚动效果
2019/05/22 Javascript
vue2.* element tabs tab-pane 动态加载组件操作
2020/07/19 Javascript
Python模块学习 filecmp 文件比较
2012/08/27 Python
使用python对文件中的单词进行提取的方法示例
2018/12/21 Python
python模拟实现斗地主发牌
2020/01/07 Python
python爬虫实现获取下一页代码
2020/03/13 Python
韩国CJ食品专卖网:CJonmart
2016/09/11 全球购物
阿玛尼美妆加拿大官方商城:Giorgio Armani Beauty加拿大
2017/10/24 全球购物
医科大学生毕业的自我评价分享
2013/11/12 职场文书
2014全国两会学习心得体会2000字
2014/03/10 职场文书
跑操口号
2014/06/12 职场文书
我们的节日中秋节活动总结
2015/03/23 职场文书
项目投资意向书范本
2015/05/09 职场文书
2015年小学体育教师工作总结
2015/10/23 职场文书
mysql 8.0.24 安装配置方法图文教程
2021/05/12 MySQL