热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP版表格展示无限级分类

TreeTable是一个能把无限分类展现为表格形式的PHP类库插件,分类的层级表示为表格的列,分类的行数表格分类的总数,单元格显示分类名称.TreeTable通过对单元格的行合并和列合并实现了无...
TreeTable是一个能把无限分类展现为表格形式的PHP类库插件,分类的层级表示为表格的列,分类的行数表格分类的总数,单元格显示分类名称.

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

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

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()只生产表体部门,请自行构建.

php完整代码如下:

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[&#39;column&#39;] == $column){ 
                       $row_level++; 
                       $this->arr[$key][&#39;column_level&#39;]  = $row_level; 
                   } 
               } 
           } 
            
           // 重新计算以ID作为键名 
        foreach ($this->arr as $k=>$v) { 
            $arr[$v[&#39;id&#39;]] = $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][&#39;parentid&#39;]; 
        $pid = $this->arr[$pid][&#39;parentid&#39;]; 
        if(is_array($this->arr)){ 
            foreach($this->arr as $id => $a){ 
                if($a[&#39;parentid&#39;] == $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[&#39;parentid&#39;] == $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][&#39;parentid&#39;]) { 
            $level++; 
            $this->get_level($this->arr[$myid][&#39;parentid&#39;], 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[&#39;id&#39;], false); 
            } 
        }else{ 
            $count++; 
        } 
        return $count; 
    } 
     
    /** 
     * 获取节点所有子节点ID号 
     * @param $catid 节点ID号 
     * @param $init 第一次加载将情况static初始化 
     * */ 
    public function get_arrchildid($myid, $init = true) { 
        static $childid; 
        if($init) $childid = &#39;&#39;; 
        if(!is_array($this->arr)) return false; 
        foreach($this->arr as $id => $a){ 
            if($a[&#39;parentid&#39;] == $myid) { 
                $childid = $childid ? $childid.&#39;,&#39;.$a[&#39;id&#39;] : $a[&#39;id&#39;]; 
                $this->get_arrchildid($a[&#39;id&#39;], false); 
            } 
        } 
        return $childid ; 
    } 
     
    /** 
     * 获取该节点所有父节点ID号 
     * @param $id 节点ID号 
     * */ 
    public function get_arrparentid($id, $arrparentid = &#39;&#39;) { 
        if(!is_array($this->arr)) return false; 
        $parentid = $this->arr[$id][&#39;parentid&#39;]; 
        if($parentid > 0) $arrparentid = $arrparentid ? $parentid.&#39;,&#39;.$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[&#39;id&#39;]) { 
                  $node_row_count = 0; 
                $arrparentid = explode(&#39;,&#39;, $node[&#39;arrparentid&#39;]); 
                // 所有父节点小于当前节点层次的底层节点等于0的元素 
                foreach ($arrparentid as $pid){ 
                    foreach ($nodearr as $node_row){ 
                        if($node_row[&#39;column&#39;] == $nodearr[$pid][&#39;column&#39;] && $nodearr[$pid][&#39;column_level&#39;] > $node_row[&#39;column_level&#39;] && $node_row[&#39;child_bottom_num&#39;] == 0){ 
                            $node_row_count ++; 
                        } 
                    }     
                } 
                // 所有当前节点并且节点层次(rowid_level)小于当前节点层次的个数 
                foreach ($nodearr as $node_row){ 
                    if($node[&#39;column&#39;] == $node_row[&#39;column&#39;] && $node_row[&#39;column_level&#39;] <$node[&#39;column_level&#39;]){ 
                        $node_row_count += $node_row[&#39;child_bottom_num&#39;] ? $node_row[&#39;child_bottom_num&#39;] : 1; 
                    } 
                } 
                $node_row_count++; 
                break; 
            } 
        } 
        return $node_row_count;     
    } 
     
    /** 
     * 获取表格的行数 
     * */ 
    public function get_rows(){ 
        $row = 0; 
        foreach ($this->arr as $key => $node){ 
            if($node[&#39;child_bottom_num&#39;] == 0){ 
                $rows++; // 总行数 
            } 
        } 
        return $rows; 
    } 
     
    /** 
     * 获取表格的列数 
     * */ 
    public function get_columns(){ 
        $columns = 0 ; 
        foreach ($this->arr as $key => $node){ 
            if($node[&#39;column&#39;] > $columns){ 
                $columns = $node[&#39;column&#39;]; // 总列数 
            } 
        } 
        return $columns; 
    } 
     
    /** 
     * 获取分类的表格展现形式(不包含表头) 
     * */ 
    public function get_treetable(){ 
        $table_string = &#39;&#39;; 
        for($row = 1; $row <= $this->rows; $row++){ 
            $table_string .= "rt"; 
            foreach ($this->arr as $v){ 
                if($v[&#39;row&#39;] == $row){ 
                    $rowspan = $v[&#39;rowspan&#39;] ? "rowspan=&#39;{$v[&#39;rowspan&#39;]}&#39;" : &#39;&#39;; 
                    $colspan = $v[&#39;colspan&#39;] ? "colspan=&#39;{$v[&#39;colspan&#39;]}&#39;" : &#39;&#39;; 
                    $table_string .= "rtt 
                    {$v[&#39;name&#39;]} 
                    "; 
                } 
            } 
            $table_string .= "rt"; 
        }
        return $table_string; 
    } 
}

推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 本文介绍了求解gcdexgcd斐蜀定理的迭代法和递归法,并解释了exgcd的概念和应用。exgcd是指对于不完全为0的非负整数a和b,gcd(a,b)表示a和b的最大公约数,必然存在整数对x和y,使得gcd(a,b)=ax+by。此外,本文还给出了相应的代码示例。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 电销机器人作为一种人工智能技术载体,可以帮助企业提升电销效率并节省人工成本。然而,电销机器人市场缺乏统一的市场准入标准,产品品质良莠不齐。创业者在代理或购买电销机器人时应注意谨防用录音冒充真人语音通话以及宣传技术与实际效果不符的情况。选择电销机器人时需要考察公司资质和产品品质,尤其要关注语音识别率。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
author-avatar
傻咾厷叫我洪儿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有