无限级分类(PHP)
在处理业务的过程中,常常会遇到具有层级关系的分类表结构,这类数据在数据表中基本上是通过上级字段(如:pid)进行关联来体现它们之间的上下级关系,但如果从数据表中直接查询出来,从视觉效果上来看,它们是无序的,也就是没有进一步根据归类。PHP中可以通过这两方式对数据进行组织、归类:递归方式、引用方式。
一、数据表结构
创建一张表用于测试,表结构如下(复制SQL到Navicat下运行):
CREATE TABLE `category` (
`category_id` int(11) NOT NULL AUTO_INCREMENT,
`category_name` varchar(100) NOT NULL,
`level` int(10) NOT NULL,
`pid` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `id` (`id`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=97 DEFAULT CHARSET=utf8
自行添加测试数据,下面以行政区域为例。
二、数据结构
从数据库查询出来的数据结构,是一个二维数组:
array(6) {
[0]=>
array(4) {
["category_id"]=>
string(1) "3"
["pid"]=>
string(1) "0"
["level"]=>
string(1) "1"
["category_name"]=>
string(6) "广东"
}
[1]=>
array(4) {
["category_id"]=>
string(1) "4"
["pid"]=>
string(1) "0"
["level"]=>
string(1) "1"
["category_name"]=>
string(6) "福建"
}
[2]=>
array(4) {
["category_id"]=>
string(1) "5"
["pid"]=>
string(1) "3"
["level"]=>
string(1) "2"
["category_name"]=>
string(6) "广州"
}
[3]=>
array(4) {
["category_id"]=>
string(1) "6"
["pid"]=>
string(1) "5"
["level"]=>
string(1) "3"
["category_name"]=>
string(9) "天河区"
}
[4]=>
array(4) {
["category_id"]=>
string(1) "7"
["pid"]=>
string(1) "4"
["level"]=>
string(1) "2"
["category_name"]=>
string(9) "泉州市"
}
[5]=>
array(4) {
["category_id"]=>
string(1) "8"
["pid"]=>
string(1) "7"
["level"]=>
string(1) "3"
["category_name"]=>
string(9) "泉港区"
}
}
三、归类方式
递归方式(方式一)
/**
* 获取分类
* @param array 分类数组
* @param pid 父id
*/
public function actionGettree($array, $pid=0) {// 没存level值时,可以加第三个参数$level=1
static $list = [];
foreach ($array as $key => $value) {
if($value['pid'] == $pid){
$value['level']=$value['level'];// 添加分类时已存level值,如果没有,可以给加第三个参数$level=1,递归加一就行
$list[]=$value;
unset($array[$key]);
$this->actionGettree($array,$value['category_id']);// 没存level值时,这里第三个参数$level+1就行
}
}
return $list;
}
--------------------------------------------------------------------------
返回结果:
[0]=>
array(4) {
["category_id"]=>
string(1) "3"
["pid"]=>
string(1) "0"
["level"]=>
string(1) "1"
["category_name"]=>
string(6) "广东"
}
[1]=>
array(4) {
["category_id"]=>
string(1) "5"
["pid"]=>
string(1) "3"
["level"]=>
string(1) "2"
["category_name"]=>
string(6) "广州"
}
[2]=>
array(4) {
["category_id"]=>
string(1) "6"
["pid"]=>
string(1) "5"
["level"]=>
string(1) "3"
["category_name"]=>
string(9) "天河区"
}
[3]=>
array(4) {
["category_id"]=>
string(1) "4"
["pid"]=>
string(1) "0"
["level"]=>
string(1) "1"
["category_name"]=>
string(6) "福建"
}
[4]=>
array(4) {
["category_id"]=>
string(1) "7"
["pid"]=>
string(1) "4"
["level"]=>
string(1) "2"
["category_name"]=>
string(9) "泉州市"
}
[5]=>
array(4) {
["category_id"]=>
string(1) "8"
["pid"]=>
string(1) "7"
["level"]=>
string(1) "3"
["category_name"]=>
string(9) "泉港区"
}
}
引用方式(方式二)
/**
* 获取分类
* @param array 分类数组
*/
public function actionGettree($array) {
$items = array();
foreach ($array as $value) {
$items[$value['category_id']] = $value;
}
$tree = array();
foreach ($items as $key => $item) {
if (isset($items[$item['pid']])) {
$items[$item['pid']]['son'][] = &$items[$key];
} else {
$tree[] = &$items[$key];
}
}
return $tree;
}
--------------------------------------------------------------------------
返回结果:
array(2) {
[0]=>
array(5) {
["category_id"]=>
string(1) "3"
["pid"]=>
string(1) "0"
["level"]=>
string(1) "1"
["category_name"]=>
string(6) "广东"
["son"]=>
array(1) {
[0]=>
array(5) {
["category_id"]=>
string(1) "5"
["pid"]=>
string(1) "3"
["level"]=>
string(1) "2"
["category_name"]=>
string(6) "广州"
["son"]=>
array(1) {
[0]=>
array(4) {
["category_id"]=>
string(1) "6"
["pid"]=>
string(1) "5"
["level"]=>
string(1) "3"
["category_name"]=>
string(9) "天河区"
}
}
}
}
}
[1]=>
array(5) {
["category_id"]=>
string(1) "4"
["pid"]=>
string(1) "0"
["level"]=>
string(1) "1"
["category_name"]=>
string(6) "福建"
["son"]=>
array(1) {
[0]=>
array(5) {
["category_id"]=>
string(1) "7"
["pid"]=>
string(1) "4"
["level"]=>
string(1) "2"
["category_name"]=>
string(9) "泉州市"
["son"]=>
array(1) {
[0]=>
array(4) {
["category_id"]=>
string(1) "8"
["pid"]=>
string(1) "7"
["level"]=>
string(1) "3"
["category_name"]=>
string(9) "泉港区"
}
}
}
}
}
}