ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
``` <?php namespace Org\LAMP; class CatTree { private static $order = 'ord'; //有排序字段和表的对应,如果没有这个字段可以不写 private $id = 'typeid'; //表的id字段 private $pid = 'pid'; //表的父级pid字段 private $typename = 'name'; //表字段对应的类型名 private $son = 'subcat'; //如果有子数组,子数组下标,可以自定义值(在新数组中出现) private $level = 'level'; //默认的新加级别下标, 可以自定义值 private $path = 'path'; //默认的路径下标,可以自定义 private $ps = ','; //默认的路径分隔符号,可以自己字义 private $childs = 'childs'; //默认的子数组下标,可以自己定义 private $narr = array(); //放分完级别后的数组 private $i; //临时的一个记数 private $pathname = 'pathname'; //默认的全路径名,可以自己定义belongs //设置表字段id public function setId($value='') { $this->id=$value; } //表的父级pid字段 public function setPid($value='') { $this->pid=$value; } public function setTypename($value='') { $this->typename=$value; } public function setPathname($value='') { $this->pathname=$value; } /** * * 获取分类数结构 * 第二个参数为true时,补全父类 如:衣服/上衣/ * @param $items array 从数据库查询出来的分类信息(二维数组) * @param $allpath boolean 是否返回全路径类型名称 默认不返回提高效率 * @return 返回多维数组 */ public function getTree($items,$allpath=false){ if(empty($items)) return array(); $tree = array(); //格式化的树 $tmpMap = array(); //临时扁平数据 //如果数组中有排序字段则先排序 返回排序后的数组 if(array_key_exists(self::$order, $items[0])) {//二维数组中存在排序的字段则进行排序 usort($items, array(__CLASS__, "compare"));//用户自定义的函数或者方法排序(当前类的compare方法) } //取出id座位键名将该数据装入$tmpMap(将下标值替换成typeid) foreach ($items as $item) { $tmpMap[$item[$this->id]] = $item; } //自定义开始:取出带父类别名的类别名 if ($allpath) { foreach ($tmpMap as $key =>$temp) { //如果pid>0即存在父类别 if ($temp[$this->pid ]) { //拿到path $path=$temp[$this->path]; $pathArr=explode($this->ps, $path);//fuid数组 //取出父id数组的名字 $aname=''; foreach ($pathArr as $pid) { if ($pid!=0) { foreach ($tmpMap as $value) { if ($pid==$value[$this->id]) { $aname.=$value[$this->typename].'/'; } } }else{ continue; } } $aname= $aname.$temp[$this->typename]; }else{ $aname=$temp[$this->typename]; } $tmpMap[$key][$this->pathname]=$aname; } } //自定义结束 foreach ($items as $item) { if (isset($tmpMap[$item[$this->pid]])) { //循环原数组,原数组中的pid是临时数组的id时,将原数组的这组数据插入到子数组中 $tmpMap[$item[$this->pid]][$this->son][] = &$tmpMap[$item[$this->id]]; } else { //如果pid=0时 $tree[] = &$tmpMap[$item[$this->id]]; } } return $this->pathchild($tree); } /** * 设置类路路径, 和获取全部子类 * return eg ["childs"] => string(4) "2,3," */ private function pathchild($arr, $path='') { $xarr = array(); foreach ($arr as $k=>$v) { $xarr[$k]=$v; $xarr[$k][$this->path] = $path.$this->ps.$v[$this->pid]; $xarr[$k][$this->childs] = ''; if(isset($xarr[$k][$this->son])) { $xarr[$k][$this->son]=$this->pathchild($xarr[$k][$this->son], $xarr[$k][$this->path]); foreach($xarr[$k][$this->son] as $vv) { $xarr[$k][$this->childs] .= $vv[$this->id]; $xarr[$k][$this->childs] .= $this->ps.$vv[$this->childs]; } } } return $xarr; } /** * * 返回带有层数级别的二维数组 * @param array $arr 从表中获取的数组 * @return array 处理过的数组 */ public function getList($arr, $allpath=false) { $data=$this->getTree($arr, $allpath); return $this->clevel($data); } /** * 转多层数组为二维数组, 并加上层数组别 */ private function clevel($arr, $num=0) { $this->i = $num; //遍历多维数组 foreach ($arr as $v) { if (isset($v[$this->son])) { //遍历后存在子数组情况 $v[$this->level] = $this->i++;//depath $subcat = $v[$this->son];//将子数组临时存放 unset($v[$this->son]);//删除子数组 $v[$this->childs] = trim($v[$this->childs], $this->ps);//去除多余的分隔符 $v[$this->path] = trim($v[$this->path], $this->ps);//去除多余的分隔符 $this->narr[$v[$this->id]]=$v; $this->clevel($subcat, $this->i); } else { $v[$this->level] = $this->i; $v[$this->childs] = trim($v[$this->childs], $this->ps); $v[$this->path] = trim($v[$this->path], $this->ps); $this->narr[$v[$this->id]]=$v; } } $this->i--; return $this->narr; } /** * 内部使用方法, 将按二维数组中的指定排序字段排序 */ private static function compare($x,$y){ if($x[self::$order] == $y[self::$order]) { return 0; } elseif($x[self::$order] < $y[self::$order]){ return -1; } else { return 1; } } } ``` ``` $tree=new Org\LAMP\CatTree(); $tree->setId('partsid'); $tree->setPid('parentid'); $tree->setTypename('pname'); $list=$tree->getList($partsList,true); ```