PHP无限分类(树形类)


Posted in PHP onSeptember 28, 2013
<?php
//模拟PHP无限分类查询结果
return array(
    array(
        'id'=>1,
        'pid'=>0,
        'name'=>'主页'
    ),
    array(
        'id'=>2,
        'pid'=>0,
        'name'=>'新闻'
    ),
    array(
        'id'=>3,
        'pid'=>0,
        'name'=>'媒体'
    ),
    array(
        'id'=>4,
        'pid'=>0,
        'name'=>'下载'
    ),
    array(
        'id'=>5,
        'pid'=>0,
        'name'=>'关于我们'
    ),
    array(
        'id'=>6,
        'pid'=>2,
        'name'=>'天朝新闻'
    ),
    array(
        'id'=>7,
        'pid'=>2,
        'name'=>'海外新闻'
    ),
    array(
        'id'=>8,
        'pid'=>6,
        'name'=>'州官新闻'
    ),
    array(
        'id'=>9,
        'pid'=>3,
        'name'=>'音乐'
    ),
    array(
        'id'=>10,
        'pid'=>3,
        'name'=>'电影'
    ),
    array(
        'id'=>11,
        'pid'=>3,
        'name'=>'小说'
    ),
    array(
        'id'=>12,
        'pid'=>9,
        'name'=>'铃声'
    ),
    array(
        'id'=>13,
        'pid'=>9,
        'name'=>'流行音乐'
    ),
    array(
        'id'=>14,
        'pid'=>9,
        'name'=>'古典音乐'
    ),
    array(
        'id'=>15,
        'pid'=>12,
        'name'=>'热门铃声'
    ),
    array(
        'id'=>16,
        'pid'=>12,
        'name'=>'搞笑铃声'
    ),
    array(
        'id'=>17,
        'pid'=>12,
        'name'=>'MP3铃声'
    ),
    array(
        'id'=>18,
        'pid'=>17,
        'name'=>'128K'
    ),
    array(
        'id'=>19,
        'pid'=>8,
        'name'=>'娱乐新闻'
    ),
    array(
        'id'=>20,
        'pid'=>11,
        'name'=>'穿越类'
    ),
    array(
        'id'=>21,
        'pid'=>11,
        'name'=>'武侠类'
    ),
);
?>

     拉风归拉风,但是那些文章提供的无限分类的类相关操作有点挫,直接把对数据库操作也封装进去了。也就是别人要用你这个类,还要跟你建一样的表,真TM恶心。由于项目要用到,所以自己写了一个PHP无限分类的类(也称树形类),没有数据库的操作,只需要实例化的时候传进去结果集,也就是树形数组。再执行leaf方法或navi方法即可得到想要的结果,下面请看源码,看完之后奉上smarty模板引擎的相应的模板递归方法。

<?php
/**
 * 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;
    }
}
?>

在smarty中的PHP无限分类的使用方法:

$result=$db->query(……);//这里查询得到结果集,注意结果集为数组
$tree= new Tree($result);
$arr=$tree->leaf(0);
$nav=$tree->navi(15);
$smarty->assign(‘arr',$arr);
$smarty->assign(‘nav',$nav);
$smarty->display(‘test.html');

在smarty模板中这样递归:

<!--导航-->
<div id="navigator">
<{foreach $nav as $n}>
    <{if $n@iteration != $n@last}>
        <{$n.name}> ->
    <{else}>
        <{$n.name}>
    <{/if}>
<{/foreach}>
</div>
<!--树形菜单-->
<div id="menu">
<{function name=menu}>
    <ul>
        <{foreach $data as $entry}>
            <li>
                <span><{$entry.name}></span> <{*注意字段要改成自己的字段哦*}>
            <{if isset($entry.child)}>
                <{call name=menu data=$entry.child}>
            <{/if}>
            </li>
        <{/foreach}>
    </ul>
<{/function}>
<{call name=menu data=$arr}> <{*注意在这里$arr才是模板变量*}>
</div>

转载请申明来自kvoid.com

当然,你也可以更改递归方法,用你想的标签不受拘束。HTML+PHP混编的递归方法这里就不贴了,我也懒得写,最讨厌混编,看着恶心,在这里推荐一下jake前辈的SpeedPHP框架,由于默认的引擎是smarty,我的这个PHP无限分类完全兼容SP框架。同样的,jquery的treeview插件和下拉菜单插件也完美支持。

对了,建议使用Smarty强大的缓存功能,缓存才是王道。

PHP 相关文章推荐
php正则表达式(regar expression)
Sep 10 PHP
解析link_mysql的php版
Jun 30 PHP
php 模拟 asp.net webFrom 按钮提交事件的思路及代码
Dec 02 PHP
PHP大转盘中奖概率算法实例
Oct 21 PHP
php使用递归函数实现数字累加的方法
Mar 16 PHP
CI框架数据库查询之join用法分析
May 18 PHP
Yii2针对指定url的生成及图片等的引入方法小结
Jul 18 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
Jul 19 PHP
php实现的统计字数函数定义与使用示例
Jul 26 PHP
PHP设计模式之模板方法模式定义与用法详解
Apr 02 PHP
PHP _construct()函数讲解
Feb 03 PHP
Laravel框架Blade模板简介及模板继承用法分析
Dec 03 PHP
PHP的PSR规范中文版
Sep 28 #PHP
PHP中time(),date(),mktime()区别介绍
Sep 28 #PHP
php中time()和mktime()方法的区别
Sep 28 #PHP
PHP用strstr()函数阻止垃圾评论(通过判断a标记)
Sep 28 #PHP
PHP利用REFERER根居访问来地址进行页面跳转
Sep 28 #PHP
PHP strstr 函数判断字符串是否否存在的实例代码
Sep 28 #PHP
PHP JS Ip地址及域名格式检测代码
Sep 27 #PHP
You might like
PHP实现UTF-8文件BOM自动检测与移除实例
2014/11/05 PHP
PHP使用array_multisort对多个数组或多维数组进行排序
2014/12/16 PHP
php图片水印添加、压缩、剪切的封装类实现
2020/04/18 PHP
php生成mysql的数据字典
2016/07/07 PHP
ThinkPHP5.0 图片上传生成缩略图实例代码说明
2018/06/20 PHP
Smarty模板类内部原理实例分析
2019/07/03 PHP
css图片自适应大小
2007/11/28 Javascript
网页中返回顶部代码(多种方法)另附注释说明
2013/04/24 Javascript
js/html光标定位的实现代码
2013/09/23 Javascript
js调用iframe实现打印页面内容的方法
2014/03/04 Javascript
Area 区域实现post提交数据的js写法
2014/04/22 Javascript
jQuery实现可展开合拢的手风琴面板菜单
2015/09/15 Javascript
JS+CSS实现分类动态选择及移动功能效果代码
2015/10/19 Javascript
jQuery中判断对象是否存在的方法汇总
2016/02/24 Javascript
无缝滚动的简单实现代码(推荐)
2016/06/07 Javascript
Bootstrap3 内联单选和多选框
2016/12/29 Javascript
vue component 中引入less文件报错 Module build failed
2019/04/17 Javascript
pycharm 使用心得(三)Hello world!
2014/06/05 Python
详解Django框架中用context来解析模板的方法
2015/07/20 Python
python中enumerate函数遍历元素用法分析
2016/03/11 Python
Python3解释器知识点总结
2019/02/19 Python
Python selenium模块实现定位过程解析
2020/07/09 Python
微信小程序之html5 canvas绘图并保存到系统相册
2019/06/20 HTML / CSS
科沃斯机器人官网商城:Ecovacs
2016/08/29 全球购物
墨尔本照明批发商店:Mica Lighting
2017/12/28 全球购物
英国泽西岛植物:Jersey Plants Direct
2019/08/07 全球购物
旅游管理专业生自荐信范文
2014/01/02 职场文书
上课看小说检讨书
2014/02/22 职场文书
工作检讨书怎么写
2014/10/10 职场文书
教师党员批评与自我批评发言稿
2014/10/15 职场文书
法人代表资格证明书
2015/06/18 职场文书
图书借阅制度范本
2015/08/06 职场文书
中学生运动会广播稿
2015/08/19 职场文书
《清澈的湖水》教学反思
2016/02/17 职场文书
windows11怎么查看自己安装的版本号? win11版本号的查看方法
2021/11/21 数码科技
ubuntu如何搭建vsftpd服务器
2022/12/24 Servers