在内容管理系统、电商商品分类、部门组织架构等场景中,无限级分类和树形数据结构是非常常见的需求,CodeIgniter作为轻量级的PHP框架,本身没有内置处理这类数据的内置方法,需要开发者结合合理的表结构和逻辑代码来实现。

数据库表结构设计
要实现无限级分类,首先需要在数据库设计阶段预留父级ID字段,用来标识当前分类的上级分类,表结构示例如下:
-- 创建分类表 CREATE TABLE `ci_category` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '分类名称', `parent_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '父级分类ID,0表示顶级分类', `sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序权重', PRIMARY KEY (`id`), KEY `idx_parent_id` (`parent_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='无限级分类表';
模型层实现数据查询
在CodeIgniter中,我们可以在模型层封装分类相关的查询方法,首先创建Category_model模型:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Category_model extends CI_Model {
// 分类表名
protected $table = 'ci_category';
public function __construct() {
parent::__construct();
$this->load->database();
}
/**
* 获取所有分类数据
* @return array 所有分类的扁平数组
*/
public function getAllCategories() {
$query = $this->db->order_by('parent_id', 'ASC')
->order_by('sort', 'DESC')
->get($this->table);
return $query->result_array();
}
/**
* 根据父级ID获取子分类
* @param int $parentId 父级ID
* @return array 子分类数组
*/
public function getChildrenByParentId($parentId) {
$query = $this->db->where('parent_id', $parentId)
->order_by('sort', 'DESC')
->get($this->table);
return $query->result_array();
}
}
扁平数据转树形结构
从数据库查询出来的分类数据通常是扁平的二维数组,需要将其转换为树形结构方便前端渲染或者层级操作,我们可以封装一个通用的转换方法:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Category_model extends CI_Model {
// 分类表名
protected $table = 'ci_category';
public function __construct() {
parent::__construct();
$this->load->database();
}
/**
* 获取所有分类数据
* @return array 所有分类的扁平数组
*/
public function getAllCategories() {
$query = $this->db->order_by('parent_id', 'ASC')
->order_by('sort', 'DESC')
->get($this->table);
return $query->result_array();
}
/**
* 根据父级ID获取子分类
* @param int $parentId 父级ID
* @return array 子分类数组
*/
public function getChildrenByParentId($parentId) {
$query = $this->db->where('parent_id', $parentId)
->order_by('sort', 'DESC')
->get($this->table);
return $query->result_array();
}
/**
* 将扁平分类数组转换为树形结构
* @param array $list 扁平分类数组
* @param int $parentId 起始父级ID
* @return array 树形结构数组
*/
public function listToTree($list, $parentId = 0) {
$tree = [];
foreach ($list as $item) {
if ($item['parent_id'] == $parentId) {
// 递归查找子分类
$children = $this->listToTree($list, $item['id']);
if (!empty($children)) {
$item['children'] = $children;
}
$tree[] = $item;
}
}
return $tree;
}
/**
* 获取完整的树形分类数据
* @return array 树形分类数组
*/
public function getCategoryTree() {
$allCategories = $this->getAllCategories();
return $this->listToTree($allCategories, 0);
}
}
控制器中调用逻辑
我们可以在控制器中调用模型的方法,获取树形分类数据并传递给视图渲染:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Category extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->model('Category_model');
}
/**
* 分类列表页面
*/
public function index() {
$data['category_tree'] = $this->Category_model->getCategoryTree();
$this->load->view('category/index', $data);
}
/**
* 获取分类树形数据接口
*/
public function getTree() {
$tree = $this->Category_model->getCategoryTree();
$this->output->set_content_type('application/json')
->set_output(json_encode(['code' => 0, 'data' => $tree, 'msg' => 'success']));
}
}
视图层渲染树形分类
在视图中我们可以递归渲染树形分类,这里以无序列表的形式展示:
<!-- 视图文件 category/index.php -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>无限级分类展示</title>
</head>
<body>
<h3>分类列表</h3>
<?php
// 递归渲染分类的方法
function renderCategoryTree($tree) {
if (empty($tree)) {
return '';
}
$html = '<ul>';
foreach ($tree as $item) {
$html .= '<li>' . htmlspecialchars($item['name']);
if (!empty($item['children'])) {
$html .= renderCategoryTree($item['children']);
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
}
echo renderCategoryTree($category_tree);
?>
</body>
</html>
性能优化建议
如果分类数据量较大,递归查询可能会导致性能问题,我们可以采用以下方式优化:
- 给
parent_id字段添加索引,加快按父级ID查询的速度 - 对于不常变动的分类数据,可以在更新分类时生成树形结构缓存,查询时直接读取缓存
- 如果只需要获取某个分类下的所有子分类ID,可以使用路径枚举的方式存储分类路径,比如添加
path字段存储类似0,1,3,5的路径,查询时通过LIKE '0,1,%'快速获取所有子分类
总结
在CodeIgniter框架中实现无限级分类和树形数据结构处理,核心是先设计合理的带父级ID的表结构,然后通过模型层查询所有扁平数据,再使用递归或者迭代的方式将扁平数据转换为树形结构。这种方式逻辑清晰,扩展性较好,能够满足大部分项目的层级数据处理需求。如果数据量较大,再结合缓存或者路径枚举等方式做进一步优化即可。
CodeIgniter无限级分类树形数据结构php修改时间:2026-06-17 18:31:00