一、递归
//递归
//树形的类
class Tree
{
protected $data;
public $treeList;
public function __construct()
{
$catalog= new Catalog();//实例化分类的model
$this->data=$catalog->show();//将要分类的数据查询出来
$this->treeList=$this->tree($result,0,0);//构造中就执行了分类方法
}
/**
* $result为存放数据的空数组
* $pid 为数据表字段中的pid 初始为0 顶级类别先查询
* $spac 为计数器
*/
public function tree(&$result=array(),$pid,$spac){
$spac=$spac+4;
foreach($this->data as $value){
if($value['p_id']==$pid){
$value['catalog_name'] = str_repeat(' ',$spac)."|--".$value['catalog_name'];
$result[] = $value;
unset($value); //把这个节点从数组中移除,减少后续递归消耗
$this->tree($result,$value['catalog_id'],$spac);
}
}
return $result;
}
}
//其他界面调用的代码
$tree=new Tree();
$tree_list=$tree->treeList;
二、引用
//假设这是我们数据库查询出来的数据(二维数组)
$arr=[
[
'tid' => 1,
'tname' => '亚洲',
'p_id' =>0],
[
'tid' => 2,
'tname' => '欧洲' ,
'p_id' => 0],
[
'tid' => 3,
'tname' => '非洲' ,
'p_id' => 0],
[
'tid' => 4,
'tname' => '中国',
'p_id' => 1],
[
'tid' => 5,
'tname' => '美洲',
'p_id' => 0],
[
'tid' => 6,
'tname' => '台湾',
'p_id' => 4],
[
'tid' => 7,
'tname' => '墨西哥' ,
'p_id' => 5]
];
function generateTree($array){
//第一步 构造数据 为上面的数组加上索引
$items = array();
foreach($array as $value){
$items[$value['tid']] = $value;
}
//第二步 遍历数据 生成树状结构
$tree = array();
foreach($items as $key => &$value){
if(isset($items[$value['p_id']])){
$items[$value['p_id']]['son'][] = &$value;
}else{
$tree[] = &$value;
}
//如果还涉及到另外一张表,另一张表的id与分类表的id一样时
//将分类和标签结合
//foreach($tags as $k=>$v){
//if ($v['catalog_id']==$value['catalog_id']){
//$value['tags'][]=$v;
//}
//}
}
return $tree;
}
//测试代码
$list=generateTree($arr);
print_r($list);
//测试的结果
Array
(
[0] => Array
(
[tid] => 1
[tname] => 亚洲
[p_id] => 0
[son] => Array
(
[0] => Array
(
[tid] => 4
[tname] => 中国
[p_id] => 1
[son] => Array
(
[0] => Array
(
[tid] => 6
[tname] => 台湾
[p_id] => 4
)
)
)
)
)
[1] => Array
(
[tid] => 2
[tname] => 欧洲
[p_id] => 0
)
[2] => Array
(
[tid] => 3
[tname] => 非洲
[p_id] => 0
)
[3] => Array
(
[tid] => 5
[tname] => 美洲
[p_id] => 0
[son] => Array
(
[0] => Array
(
[tid] => 7
[tname] => 墨西哥
[p_id] => 5
)
)
)
)
拓展:根据标签查找所属的父级分类(pid=0)
2张表(分类表和标签表)
sp_type 分类表 —tid —tname 分类名称 —p_id 父级id
sp_tags 标签表 —tag_id —tag_name 标签名称 —tid 对应的分类表id
需求:传入tag_id 数组,查询对应的分类表最顶级分类 p_id=0
$tag = input('');
$tags_res = Db::name('tags')
->where('tag_id', 'in', $tag['tags_id'])
->join('sp_type', 'sp_type.tid=sp_tags.tid')
->select();
//最初结果
array (size=2)
0 =>
array (size=5)
'tag_id' => int 2
'tag_name' => string '非洲大草原' (length=15)
'tid' => int 2
'tname' => string '非洲' (length=6)
'p_id' => int 0
1 =>
array (size=5)
'tag_id' => int 7
'tag_name' => string '泉州' (length=6)
'tid' => int 6
'tname' => string '福建' (length=6)
'p_id' => int 20
----------------------------------------------------------------------
for ($i = 0; $i < count($tags_res); $i++) {
$res[] = $this->getZero($tags_res[$i]);
}
public function getZero($param)
{
$type = Db::name('type')->select();
while (true) {
if ($param['p_id'] == 0) {
return $param;
}
foreach ($type as $key => $value) {
if ($value['tid'] == $param['p_id']) {
$param=[
'tid'=>$value['tid'],
'tname'=>$value['tname'],
'tag_name'=>$param['tag_name'],
'p_id'=>$value['p_id']
];
continue;
}
}
}
}
//执行结果,获得传入的标签数组对应的分类数组的顶级分类
array (size=2)
0 =>
array (size=5)
'tag_id' => int 2
'tag_name' => string '非洲大草原' (length=15)
'tid' => int 2
'tname' => string '非洲' (length=6)
'p_id' => int 0
1 =>
array (size=4)
'tid' => int 1
'tname' => string '亚洲' (length=6)
'tag_name' => string '泉州' (length=6)
'p_id' => int 0