当前位置: 首页 > 后端技术 > PHP

PHP实现无限分类

时间:2023-03-29 18:20:11 PHP

最近打算做一个博客,一般每篇文章都有自己的分类。下面记录下自己写博客时实现无限分类的过程。php框架使用的是laravel,根据评论可以很方便的换成自己习惯的框架。数据表设计CREATETABLE`article_category`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`pid`int(10)unsignedNOTNULLDEFAULT'0'COMMENT'parentid',`name`char(50)COLLATEutf8mb4_unicode_ciNOTNULLCOMMENT'类别名称',`statu`enum('y','n')COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT'y'COMMENT'是否显示',`created_at`timestampNULLDEFAULTNULL,`updated_at`timestampNULLDEFAULTNULL,`remark`varchar(100)COLLATEutf8mb4_unicode_ciNOTNULLDEFAULT'',PRIMARYKEY(`id`),KEY`article_category_pid_index`(`pid`))ENGINE=MyISAMAUTO_INCREMENT=18DEFAULTCHARSET=utf8mb4COLLATE=utf8cimb;添加分类publicfunctionaddClassify(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?'操作成功':'操作失败';returnback()->with('act_msg',$result);}获取分类列表/***加载视图*@return[type][description]*/publicfunctionclassify(){//获取所有分类记录数据库$node=$this->_category->orderBy('id','asc')->get();//ClassifyAnd排序和子类排序$node=$this->_treeNode($node->toArray(),0);//加载视图并分配数据paraminteger$parentId父类id,默认主类*@returnarray*/privatefunction_treeNode($data,$parentId=0){//用来保存排序后的分类节点$node=[];//循环所有的分类foreach($dataas$key=>$value){//如果当前分类的parentid和你要找的parentid相等,写入$node数组,查找当前类别id下的所有子类别if($parentId==$value['pid']){$node[$key]=$value;$node[$key]['childer']=$this->_treeNode($data,$value['id']);}}return$node;}方法classify用于从数据库中获取所有类别并显示模板方法_treeNode是一个递归函数。对从数据库中获取的所有类别进行排序排序。排序效果如下:渲染视图ID分类名称简介更新时间发布状态运行@foreach($listas$val){{$val['id']}}{{$val['name']}}{{$val['remark']}}{{$val['updated_at']}}@if($val['statu']=='y')启用@else禁止使用@endif@if(!empty($val['childer'])){{get_childer_node($val['childer'])}}@endif@endforeach渲染视图时需要判断是否有是类别下的子类别,如果只实现三级分类,那么只需要二级循环。这里我自定义了一个递归函数get_childer_node来获取该分类下的子分类。具体实现如下:/***获取子节点*@paramarray$data[description]*@return[type][description]*/functionget_childer_node($data=[]){//记录深度此类别静态$callNum=1;如果(空($数据))返回;foreach($dataas$key=>$val){if($val['statu']=='y')$isShow='启用';else$isShow='disable';echo<<{$val['id']}|----{$val['name']}{$val['remark']}td>{$val['updated_at']}$isShowHTML;//如果类别还有子类别,再次遍历输出if(!empty($val['childer'])){$callNum++;get_childer_node($val['childer'])']);}//重置分类级别$callNum=1;}}最终效果