1、CategoryTree.php
注意:由于是PHP实现无限级分类,以下代码中,
$arr指的是查询所有分类表中的数据,例如:SELECT `id`, `name`,`alias`, `parent_id` FROM `category`
$id指的是分类的id,一般这个id是AUTO_INCREMENT自增的。
class CategoryTree{
/*
* 无限级分类,牵涉3个应用
* 1:找指定栏目的子栏目
* 2:找指定栏目的子孙栏目,即子孙树
* 3:找指定栏目的父栏目/父父栏目......顶级栏目,即家谱树
* $arr = array(
array('id'=>1,'name'=>'安徽','parent_id'=>0),
array('id'=>2,'name'=>'海淀','parent_id'=>7),
array('id'=>3,'name'=>'濉溪县','parent_id'=>5),
array('id'=>4,'name'=>'昌平','parent_id'=>7),
array('id'=>5,'name'=>'淮北','parent_id'=>1),
array('id'=>6,'name'=>'朝阳','parent_id'=>7),
array('id'=>7,'name'=>'北京','parent_id'=>0),
array('id'=>8,'name'=>'上地','parent_id'=>2)
);
*/
//找子栏目
用法:findsong($arr,0);
function findson($arr,$id=0){
//$id栏目的儿子有哪些?
//答:数组循环一遍,谁的parent值 等于 $id ,谁就是他儿子
$sons = array();//子栏目父组
foreach ($arr as $k => $v){
if($v['parent_id'] == $id){
$sons[] = $v;
}
}
return $sons;
}
//找子孙树 递归 用静态变量:static
/*
在函数中声明的static静态变量,无论此函数调用多少次,只初始化一次
以后就会直接沿用该变量,这在递归时,很有用
static总结
1:修饰类的属性与方法为静态属性,静态方法
2:static::method(),延迟绑定
3:在函数方法中,声明静态变量用
*/
function sub_tree($arr,$id=0,$lev=1){
static $subs = array();//子栏目父组
foreach ($arr as $v){
if($v['parent_id'] == $id){
$v['lev'] = $lev;
$subs[] = $v;
$this->sub_tree($arr,$v['id'],$lev+1);
}
}
return $subs;
}
/*
用法:
$tree = (subtree($arr,0,1));
foreach($tree as $v){
echo str_repeat(' ',$v['lev']).$v['name'].'
';
}*/
//找子孙树 递归
function subtree($arr,$id=0,$lev=1){
$subs = array();//子栏目父组
foreach ($arr as $v){
if($v['parent_id'] == $id){
$v['lev'] = $lev;
$subs[] = $v;
$subs = array_merge($subs,$this->subtree($arr,$v['id'],$lev+1));
}
}
return $subs;
}
//子孙树 表单 select option html输出
function getsubtree_select_option($tree){
if($tree){
$str = '';
foreach($tree as $v){
$str .= ''.str_repeat(' ',$v['lev']).$v['name'].'';
}
}else{
$str = "";
}
return $str;
}
//子孙树 表单 select table html输出
function getsubtree_table_option($tree){
}
//找父栏目/父父栏目......顶级栏目,即家谱树。 主要用于面包屑
//第一种方法 用静态变量:static
//用法:family_tree_static($arr,8);
function family_tree_static($arr,$id){
static $tree = array();
foreach($arr as $v){
if($v['id'] == $id){
$tree[] = $v;//以找到上地为例子
//判断要不要找到父栏目
if($v['parent_id'] > 0){ //parent>0,说明有父栏目
$this->family_tree_static($arr,$v['parent_id']);
}
}
}
return $tree;
}
//找父栏目/父父栏目......顶级栏目,即家谱树。 主要用于面包屑
//第二种方法 非静态变量 递归
//用法:family_tree($arr,8);
function family_tree($arr,$id){
$tree = array();
foreach ($arr as $v){
if($v['id'] == $id){
$tree[] = $v;
//判断要不要找父栏目
if($v['parent_id'] > 0){ //parent>0,说明有父栏目
$tree = array_merge($tree,$this->family_tree($arr,$v['parent_id']));
}
}
}
return $tree;
}
//找父栏目/父父栏目......顶级栏目,即家谱树。 主要用于面包屑
//第三种方法 非静态变量 递归 反转
//用法:family_tree_reverse($arr,8);
function family_tree_reverse($arr,$id){
$tree = array();
foreach ($arr as $v){
if($v['id'] == $id){
//判断要不要找父栏目
if($v['parent_id'] > 0){ //parent>0,说明有父栏目
$tree = array_merge($tree,$this->family_tree_reverse($arr,$v['parent_id']));
}
$tree[] = $v;
}
}
return $tree;
}
//找父栏目/父父栏目......顶级栏目,即家谱树。 主要用于面包屑
//第四种方法:迭代
//迭代效率比递归高,代码也没多少,找家谱树推荐用迭代
//用法:familytree($arr,8);
//注意:phpstudy下测试,数据库查询结果用此方法会报500错误,直接给一个$arr格式的数组 又返回正常
function tree($arr,$id){
$tree = array();
while($id !== 0){
foreach($arr as $v){
if($v['id'] == $id){
$tree[] = $v;
$id = $v['parent_id'];
break;
}
}
}
return $tree;
}
}
2、简单使用方法:
引入CategoryTree.php
实例化类:new CategoryTree();
直接调用类相应的方法
例如:
require_once ABSPATH . '../core/class/CategoryTree.php'; //无限极分类
$categorytree = new CategoryTree();
$breadcrumb = $categorytree->family_tree_reverse($category_select_all,$category_select_alias['id']); //得到面包屑
3、分类表结构:
以mysql数据库为例子,一张表即可!