无限级分类(PHP)

作者:IT技术圈子 浏览量:589   更新于 2023-09-02 13:38 标签:

在处理业务的过程中,常常会遇到具有层级关系的分类表结构,这类数据在数据表中基本上是通过上级字段(如: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) "泉港区"
          }
        }
      }
    }
  }
}