PHP无限分类

#1 Kvoid

扩展代码板块发不了帖,只有先发在这里了。详细可以在我的文章中了解,提供了smarty模板递归的写法 传送门
/**
* Tree 树型类(无限分类)
*
* @author Kvoid
* @copyright http://kvoid.com
* @version 1.0
* @access public
* @example
*   $tree= new Tree($result);
*   $arr=$tree->leaf(0);
*   $nav=$tree->navi(15);
*/
class Tree {
        private $result;
        private $tmp;
        private $arr;
        private $already = array();
        /**
         * 构造函数
         *
         * @param array $result 树型数据表结果集
         * @param array $fields 树型数据表字段,array(分类id,父id)
         * @param integer $root 顶级分类的父id
         */
        public function __construct($result, $fields = array('id', 'pid'), $root = 0) {
                $this->result = $result;
                $this->fields = $fields;
                $this->root = $root;
                $this->handler();
        }
        /**
         * 树型数据表结果集处理
         */
        private function handler() {
                foreach ($this->result as $node) {
                        $tmp[$node[$this->fields[1]]][] = $node;
                }
                krsort($tmp);
                for ($i = count($tmp); $i > 0; $i--) {
                        foreach ($tmp as $k => $v) {
                                if (!in_array($k, $this->already)) {
                                        if (!$this->tmp) {
                                                $this->tmp = array($k, $v);
                                                $this->already[] = $k;
                                                continue;
                                        } else {
                                                foreach ($v as $key => $value) {
                                                        if ($value[$this->fields[0]] == $this->tmp[0]) {
                                                                $tmp[$k][$key]['child'] = $this->tmp[1];
                                                                $this->tmp = array($k, $tmp[$k]);
                                                        }
                                                }
                                        }
                                }
                        }
                        $this->tmp = null;
                }
                $this->tmp = $tmp;
        }
        /**
         * 反向递归
         */
        private function recur_n($arr, $id) {
                foreach ($arr as $v) {
                        if ($v[$this->fields[0]] == $id) {
                                $this->arr[] = $v;
                                if ($v[$this->fields[1]] != $this->root) $this->recur_n($arr, $v[$this->fields[1]]);
                        }
                }
        }
        /**
         * 正向递归
         */
        private function recur_p($arr) {
                foreach ($arr as $v) {
                        $this->arr[] = $v[$this->fields[0]];
                        if ($v['child']) $this->recur_p($v['child']);
                }
        }
        /**
         * 菜单 多维数组
         *
         * @param integer $id 分类id
         * @return array 返回分支,默认返回整个树
         */
        public function leaf($id = null) {
                $id = ($id == null) ? $this->root : $id;
                return $this->tmp[$id];
        }
        /**
         * 导航 一维数组
         *
         * @param integer $id 分类id
         * @return array 返回单线分类直到顶级分类
         */
        public function navi($id) {
                $this->arr = null;
                $this->recur_n($this->result, $id);
                krsort($this->arr);
                return $this->arr;
        }
        /**
         * 散落 一维数组
         *
         * @param integer $id 分类id
         * @return array 返回leaf下所有分类id
         */
        public function leafid($id) {
                $this->arr = null;
                $this->arr[] = $id;
                $this->recur_p($this->leaf($id));
                return $this->arr;
        }
}
?>

想看效果下载myapp.zip后解包运行index.php即可,可以看到与jquery.view在一起使用相当方便
4月11日,增加了leafid方法,返回传入id下的所有子分类id,方便删除分类操作。

2011-04-04 17:33:02

#2 jake

不错,转到扩展区 :handshake

2011-04-04 18:16:39

#3 elick

支持一下 :lol

2011-04-06 16:21:08

#4 chillm

:D 好东西收藏

2011-05-15 09:35:23

#5 prince

有没有更详细的使用方法?

2011-05-23 21:01:21

#6 prince

未命名.jpg

2011-06-08 20:03:43

#7 prince

效果是做出来了,但我想在类似"打印机"这个下面没有子分类的分类里生成超链接(在模板文件中做<{spUrl c=main a=list}>),应该如何判断这个分类下已经没有子分类了呢?

2011-06-08 20:06:10

#8 prince

效果是做出来了,但我想在类似"打印机"这个下面没有子分类的分类里生成超链接(在模板文件中做),应该如何 ...
prince 发表于 2011-6-8 20:06
已经做出来了,哈

2011-06-08 21:20:37

#9 free212

附件里的tree.php的代码怎么与贴出来的不一样呢?没更新吗?哪个是新的?

2011-07-17 20:21:45

#10 zhgzzy

为什么不能这样呢 ?????   $arr = spClass('Tree');

2011-08-13 13:28:51

#11 edricoo

到底如何使用??强烈要求详细说明!!!

2011-09-08 10:01:28

#12 xieguolun

有与数据库结全使用的例子吗?

2011-12-22 23:04:02

#13 xieguolun

如果是双表怎么弄呢?
如主表为  id     pid        mean            rul
               0      0          办公用品     a.php
               1      0          生活用品     b.php
               2      0          打印机       c.php
               3      1          面食
附表为    id     pid        mean            rul
               0     2          针式打印机     d.php
               1      2         激光打印机   e.php
               2     3           方便面       f.php
以此框架的一对多的查询结果像下面的样式:
array(
        array(
                'id'=>1,
                'pid'=>0,
                'name'=>'主页',
                'chend'=>array('id'=>1,
                             'pid'=>1,
                             'name'=>'主页1')
        ),
        array(
                'id'=>2,
                'pid'=>0,
                'name'=>'新闻',
                'chend'=>array('id'=>2,
                             'pid'=>2,
                             'name'=>'假新闻')
        ),
        array(
                'id'=>3,
                'pid'=>0,
                'name'=>'媒体',
                'chend'=>array(
                           ))
这怎么弄呢?请高手改一下此程序

2011-12-25 19:06:45

#14 xieguolun






  
  



<{foreach $nav as $n}>
        <{if $n@iteration != $n@last}>
                <{$n.name}>->
        <{else}>
                <{$n.name}>
        <{/if}>
<{/foreach}>



程序应该没问题,模板怎么改?

2011-12-26 07:01:11

#15 xieguolun

array(
                'id'=>7,
                'pid'=>2,
                'name'=>'海外新闻',
                'chend'=>array(
                          0=>array('id'=>5,
                                   'pid'=>7,
                                   'name'=>'日本新闻'),
                          1=>array('id'=>6,
                                   'pid'=>7,
                                   'name'=>'美国本新闻')
                        
                        )
        ),

2011-12-26 08:20:05

#16 hongrui

问一下:
1. 把分类直接写在tree中操作
2. 把分类写成js操作
3. 把分类存在数据库中

分类不超过500条,上面3种方式哪个执行效果最好,最快???

2014-05-23 10:03:44

#17 jake

hongrui 发表于 2014-5-23 10:03
问一下:
1. 把分类直接写在tree中操作
2. 把分类写成js操作
500以下数据,用2,直接通过JS在页面操作会快很多。

2014-05-23 10:08:12

#18 hongrui

jake 发表于 2014-5-23 10:08
500以下数据,用2,直接通过JS在页面操作会快很多。
如果用spAccess操作1呢??

2014-05-23 10:12:15

#19 jake

hongrui 发表于 2014-5-23 10:12
如果用spAccess操作1呢??
那要具体看系统瓶颈是在数据量还是数据读取速度了。
如果是数据量那么就多次读出来,如果是数据库慢,就要用spAccess缓存。

2014-05-23 10:29:48