在很多地方我们都需要用到无限分类,今天给大家简单的介绍一下关于PHP实现无限分类的几种方式。
递归方式
这种方式也是大家比较常用的一种方式,先来看一下主要的表结构。
id: 自增id name: 分类名称 parent_id: 父类id,顶级类值为0 sort: 排序值
代码部分:
<?php
/**
* @param list array 二维数组
* @param pid int 父级编号
* @parma level int 层级
* @param html string html输出前缀
*/
function tree($list, $pid = 0, $level = 1, $html = ' -- '){
$tree = array();
foreach ($list as $v) {
if ($v['parent_id'] == $pid) {
$v['sort'] = $level;
$v['html'] = '|' . str_repeat($html, $level);
$tree[] = $v;
$tree = array_merge($tree, tree($list, $v['id'], $level + 1, $html));
}
}
return $tree;
}
?>
引用方式
其实PHP引用是一个不错的东东,可以使用引用来组织数据。
<?php
/**
* @param $data 需要处理的数组
*/
function tree($data){
$items = array();
foreach ($data as $val) {
$items[$val['id']] = $val;
}
unset($data);
$tree = array();
foreach ($items as $item) {
if (isset($items[$item['parent_id']])) {
$items[$item['parent_id']]['son'][] = &$items[$item['id']];
} else {
$tree[] = &$items[$item['id']];
}
}
return $tree;
}
?>
基于左右编码值
这种方式的关键点在于数据库的设计,主要表结构如下:
id: 自增id name: 分类名称 lft: 左值 rgt: 右值 level: 层级数
具体看一个比较形象的例子,如水果的分类
Food : 食物 Fruit : 水果 Red : 红色 Cherry: 樱桃 Yellow: 黄色 Banana: 香蕉 Meat : 肉类 Beef : 牛肉 Pork : 猪肉
把上面的分类,组织成一个二叉树的结构,并在每个分类的左右标值,如下图:
从图中来看,我们要得到水果下面的所有分类,那么只需要用到下面的SQL语句:
SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;
通过下面代码便可很快的输出树形结构
<?php
function tree($root){
// 得到根节点的左右值
$result = mysql_query("
SELECT lft, rgt
FROM tree
WHERE name = '" . $root . "'
;"
);
$row = mysql_fetch_array($result);
// 准备一个空的右值堆栈
$right = array();
// 获得根基点的所有子孙节点
$result = mysql_query("
SELECT name, lft, rgt
FROM tree
WHERE lft BETWEEN '" . $row['lft'] . "' AND '" . $row['rgt'] ."'
ORDER BY lft ASC
;"
);
// 显示每一行
while ($row = mysql_fetch_array($result)) {
// only check stack if there is one
if (count($right) > 0) {
// 检查我们是否应该将节点移出堆栈
while ($right[count($right) - 1] < $row['rgt']) {
array_pop($right);
}
}
// 缩进显示节点的名称
echo str_repeat(' ',count($right)) . $row['name'] . "\n";
// 将这个节点加入到堆栈中
$right[] = $row['rgt'];
}
}
?>