资讯专栏INFORMATION COLUMN

PHP 实现无限分类

ysl_unh / 1036人阅读

摘要:下面就记录下我在写时实现无限分类的过程。方法是一个递归函数。这边我自定义了一个递归函数用于获取该分类下的子分类。具体实现如下获取子节点记录该分类的深度启用禁用如果该分类的依旧有子分类则再次遍历输出重置分类层级最终效果

最近打算做一个blog,通常每篇文章都有属于自己的分类。下面就记录下我在写blog时实现无限分类的过程。php框架用的是laravel,根据注释也能轻松改成你习惯的框架。

数据表设计
CREATE TABLE `article_category` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `pid` int(10) unsigned NOT NULL DEFAULT "0" COMMENT "父id",
  `name` char(50) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT "分类名",
  `statu` enum("y","n") COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "y" COMMENT "是否显示",
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `remark` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT "",
  PRIMARY KEY (`id`),
  KEY `article_category_pid_index` (`pid`)
) ENGINE=MyISAM AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
程序设计 添加分类
public function addClassify(Request $request)
{
    // laravel 框架自带的验证机制
    $this->validate(
        $request,
        [
            "name" => "required|unique:article_category",
            "remark" => "max:100",
            "pid" => "required|numeric"
        ],
        [
            "name.required" => "请填写分类名!",
            "name.unique" => "改分类名已存在",
            "remark.max" => "分类简介不能超过100个字符",
            "pid.numeric" => "分类id必须为数字"
        ]
    );
    // 获取分类名
    $this->_category->name = $request->input("name");
    // 获取分类父id,默认是0,为一级分类
    $this->_category->pid = $request->input("pid",0);
    // 分类简介
    $this->_category->remark = $request->input("remark");
    // 写入数据库
    $result = $this->_category->save();
    // 返回结果
    $result = $result ? "操作成功" : "操作失败";
    return back()->with("act_msg",$result);
}
获取分类列表
/**
 * 加载视图
 * @return [type] [description]
 */
public function classify()
{    
    // 从数据库获取所有分类记录
    $node = $this->_category->orderBy("id","asc")->get();
    // 将分类以及子分类整理排序
    $node = $this->_treeNode($node->toArray(),0);
    // 加载视图及分配数据
    return view("admin.classify",["list"=>$node]);
}

/**
 * 整理排序所有分类
 * @param  array   $data       从数据库获取的分类
 * @param  integer $parentId 父id,默认一级分类
 * @return array 
 */
private function _treeNode($data,$parentId = 0)
{
    // 用于保存整理好的分类节点
    $node = [];
    // 循环所有分类
    foreach ($data as $key => $value) {
        // 如果当前分类的父id等于要寻找的父id则写入$node数组,并寻找当前分类id下的所有子分类
        if($parentId == $value ["pid"]) {
            $node [$key] = $value;
            $node [$key] ["childer"] = $this->_treeNode($data,$value ["id"]);
        }
    }
    return $node;
}    

方法classify是用于从数据库获取所有分类以及显示模板。方法_treeNode是一个递归函数。将从数据库获取的所有分类整理排序。排序好的效果如下图:

渲染视图

            @foreach($list as $val)
                
                @if(!empty($val ["childer"]))
                    {{get_childer_node($val ["childer"])}}
                @endif
            @endforeach
            
ID 分类名 简介 更新时间 发布状态 操作
{{$val ["id"]}} {{$val ["name"]}} {{$val ["remark"]}} {{$val ["updated_at"]}} @if($val ["statu"] == "y") 启用 @else 禁用 @endif

渲染视图时需要判断该分类下是否有子分类,如果只做到三级分类,此时只需要再来个二层循环就ok了。这边我自定义了一个递归函数get_childer_node 用于获取该分类下的子分类。具体实现如下:

/**
 * 获取子节点
 * @param  array  $data [description]
 * @return [type]       [description]
 */
function get_childer_node($data = [])
{
    // 记录该分类的深度
    static $callNum = 1;
    if(empty($data)) 
        return;
    foreach ($data as $key => $val) {
        if($val ["statu"] == "y")
            $isShow = "启用";
        else
            $isShow = "禁用";
        echo <<
                
                {$val ["id"]}
                |----{$val ["name"]}
                {$val ["remark"]}
                {$val ["updated_at"]}
                $isShow
                
                    
                    
                
            
    HTML;
        // 如果该分类的依旧有子分类则再次遍历输出 
        if(!empty($val ["childer"])) {
            $callNum ++;
            get_childer_node($val ["childer"]);
        }
        // 重置分类层级
        $callNum = 1;
    }
}
最终效果

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25802.html

相关文章

  • PHP 无限分类最佳实践

    无限级分类 是一种很常见,很必须的功能,几乎每个项目都有。 应用场景:下拉列表,树型列表等 无限级分类的类型 前端实现(前端框架一般已经实现好了,只要后端按照指定格式传数据给前端就可以生成了) 后端实现(下面主要讲这种实现) 无限级多种实现 第一种(推荐) function infiniteSort($data, $showFName, $titleFName, $pidFName = p...

    yzzz 评论0 收藏0
  • PHP框架之ThinkPHP模块开发系列八,无限分类的删除

    摘要:我们在新建一个删除前的钩子函数,再利用递归方法实现子栏目的删除。最后我们删除把钩子函数恢复到原始状态在浏览器中输入,然后点击美国一栏中的删除,此时会同时删除美国下的纽约。至此,无限级分类的删除功能操作完毕。 在此现更正一下之前的预告,之前忘记了先应该把无限级分类栏目列表功能做完,也就是删除功能还没做,所以今天我们先做删除,下一节再做面包屑导航。非常抱歉。 同时,不知道是什么原因,上一节...

    BWrong 评论0 收藏0
  • PHP中的无限分类无限嵌套评论

    摘要:可以看到,我们首先获取到了所有的数据,然后按照父级归类。无限嵌套评论先来看下这个无限嵌套评论长什么样子。文件扫描使用递归进行目录文件的扫描的栗子。 回顾 上一篇文章我们讲到实战PHP数据结构基础之递归。来回顾下什么是递归? 一般来说,递归被称为函数自身的调用。 递归在开发中的实际运用 N级分类 无限级的分类在平常的开发中是常见的需求,并且在不少面试题中都会碰到。不管你做什么项目,应该都...

    Shisui 评论0 收藏0
  • PHP中的无限分类无限嵌套评论

    摘要:可以看到,我们首先获取到了所有的数据,然后按照父级归类。无限嵌套评论先来看下这个无限嵌套评论长什么样子。文件扫描使用递归进行目录文件的扫描的栗子。 回顾 上一篇文章我们讲到实战PHP数据结构基础之递归。来回顾下什么是递归? 一般来说,递归被称为函数自身的调用。 递归在开发中的实际运用 N级分类 无限级的分类在平常的开发中是常见的需求,并且在不少面试题中都会碰到。不管你做什么项目,应该都...

    李义 评论0 收藏0
  • 使用 Baum 嵌套集合模型来实现 Laravel 模型的无限分类

    摘要:本文经授权转自社区使用嵌套集合模型来实现模型的无限极分类说明大家通常都是使用递归实现无限极分类,都知道递归效率很低,下面推荐一个的扩展包,快速让你的数据模型支持无限极树状层级结构,并且兼顾效率。 本文经授权转自 PHPHub 社区 使用 Baum 嵌套集合模型来实现 Laravel 模型的无限极分类 说明 大家通常都是使用递归实现无限极分类,都知道递归效率很低,下面推荐一个 Larav...

    superPershing 评论0 收藏0

发表评论

0条评论

ysl_unh

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<