将无限分类格式化为树形结构函数

jerry thinkphp 2015年11月19日 收藏
将无限分类表数据输出为树形结构
  1. /**
  2.      * 功能 获取树形结构   注意:callback和level参数禁止传值
  3.      * @param $model  string      表
  4.      * @param $id     int         当前ID
  5.      * @param $fields string    返回字段  前三个字段分别对应id,父id,名称  至少要包含前三个字段,返回的fullname是格式化的名称,如果表中本来有fullname字段建议做别名
  6.      * @param $condition  max    查询条件  
  7.      * @param $orderby  string    排序
  8.      * @param $self boolean     是否包含当前ID数据
  9.      * @param $onlyson  boolean    是否只返回下级
  10.      * @param $return   string    返回数据类型,ids表示只返回id集合  tree返回树形结构数据
  11.      * @return $datas array        返回的数据
  12.      */
  13.     protected function treeStructure($model='',$id=0,$fields='',$condition='',$orderby='',$self=true,$onlyson=false,$return='tree',$callback=false,$level=0){
  14.                 //验证参数类型
  15.                 if(!is_string($model) || !is_int($id) || !is_string($fields) || !(is_string($condition) || is_array($condition)) || !is_string($orderby) || !is_bool($self) || !is_bool($onlyson) || !in_array($return,array('ids','tree'))) return array();
  16.         
  17.                 //验证参数值
  18.                 $fields_arr=explode(',',$fields);
  19.         if(empty($model) || empty($fields) || count($fields_arr)<3)return array();
  20.         
  21.         //获取 id,父id,名称对应表中的字段
  22.         foreach ($fields_arr as $k=>$f){
  23.             $f=trim($f);
  24.             $f_arr=explode('as',$f);
  25.             $f_arr[0]=trim($f_arr[0]);
  26.             $f_arr[1]=trim($f_arr[1]);
  27.             $fields_arr[$k]=array('field'=>$f_arr[0],'alias'=>$f_arr[1]);
  28.             if($k==2)break;
  29.         }
  30.         $field_id=$fields_arr[0]['field'];
  31.         $field_pid=$fields_arr[1]['field'];
  32.         $field_name=$fields_arr[2]['field'];
  33.         
  34.         
  35.         $model=strtolower($model);
  36.         
  37.         //查询条件
  38.         if(!empty($condition)){
  39.             if(is_array($condition))$map=$map1=$map2=$condition;
  40.             if(is_string($condition))$map['_string']=$map1['_string']=$map2['_string']=$condition;
  41.         }
  42.         
  43.         
  44.         $map[$field_pid]=$id;
  45.         
  46.         //查询
  47.         if(empty($orderby)){
  48.             $list=M()->table($model)->field($fields)->where($map)->select();
  49.         }else{
  50.             $list=M()->table($model)->field($fields)->where($map)->order($orderby)->select();
  51.         }
  52.         
  53.         $datas=array();
  54.         
  55.         //临时字段变量
  56.         $field_level=to_guid_string('level');
  57.         $field_last=to_guid_string('last');
  58.         $field_son_num=to_guid_string('son_num');
  59.         $field_all_son_num=to_guid_string('all_son_num');
  60.         
  61.         if(!$callback && $self && $id!=0){
  62.             $map1[$field_id]=$id;
  63.             $info=M()->table($model)->field($fields)->where($map1)->find();
  64.             $info[$field_level]=$level;
  65.             $info[$field_last]=1;
  66.             $info[$field_son_num]=count($list);
  67.             $datas[]=$info;
  68.             $level++;
  69.         }
  70.         
  71.         if($onlyson){
  72.             foreach ($list as $k=>$v){
  73.                 $v[$field_level]=$level;
  74.                 $v[$field_last]=(count($list)-1)==$k?1:0;
  75.                 $v[$field_son_num]=0;
  76.                 if($level==0)$info[$field_all_son_num]=0;
  77.                 $datas[]=$v;
  78.             }
  79.         }else{
  80.             if(count($list)>0){
  81.                 foreach ($list as $k=>$v){
  82.                     $v[$field_level]=$level;
  83.                     $v[$field_last]=(count($list)-1)==$k?1:0;
  84.                     $map2[$field_pid]=$v[$field_id];
  85.                     $v[$field_son_num]=M()->table($model)->where($map2)->count();//获取下级数量
  86.                     
  87.                     $next_id=intval($v[$field_id]);
  88.                     $next_level=$level+1;
  89.                     $datasx=$this->treeStructure($model,$next_id,$fields,$condition,$orderby,true,false,$return,true,$next_level);
  90.                     if($level==0){
  91.                         $v[$field_all_son_num]=count($datasx);//获取所有子级数量
  92.                     }
  93.                     $datas[]=$v;
  94.                     if(!empty($datasx)){
  95.                         foreach ($datasx as $v1){
  96.                             $datas[]=$v1;
  97.                         }
  98.                     }
  99.                 }
  100.             }
  101.         }
  102.         
  103.         if(!$callback && $self && $id!=0){
  104.             $datas[0][$field_all_son_num]=count($datas)-1;
  105.         }

  106.         if(!$callback){
  107.             $ids=array();
  108.             $all_son_num=0;
  109.             foreach ($datas as $k=>$v){
  110.                 $ids[]=$v[$field_id];
  111.                 
  112.                 if($v[$field_level]==0){
  113.                     $all_son_num=$v[$field_all_son_num];
  114.                     $i=0;
  115.                     $v['fullname']=$v[$field_name];
  116.                 }else{
  117.                     $i++;
  118.                     $prev_num=$v[$field_level]-1;
  119.                     if($prev_num>0){
  120.                         $prev_icon_t=$i==$all_son_num?'└ ':'│ ';
  121.                         $prev_icon=str_repeat('    '.$prev_icon_t,$prev_num);
  122.                     }else{
  123.                         $prev_icon='';
  124.                     }
  125.                     $icon=$v[$field_last] && $v[$field_son_num]==0?'    └ ':'    ├ ';
  126.                     $v['fullname']=$prev_icon.$icon.$v[$field_name];
  127.                 }
  128.                 unset($v[$field_level],$v[$field_last],$v[$field_son_num]);
  129.                 if(isset($v[$field_all_son_num]))unset($v[$field_all_son_num]);
  130.                 $datas[$k]=$v;
  131.             }
  132.             
  133.             if($return=='ids'){
  134.                 return $ids;
  135.             }else{
  136.                 return $datas;
  137.             }
  138.         }else{
  139.             return $datas;
  140.         }
  141.         
  142.     }
列表效果


下拉框效果