php实现无限极分类(php无限分类实现不实用递归)
- 作者: 管理员
- 来源: 投稿
- 2024-12-22
1、php实现无限极分类
2、php无限分类实现不实用递归
原因:
递归无限分类的实现不实用,原因在于:
效率低下:递归会不断创建子函数调用,导致栈空间消耗过大,对于大型分类树结构,容易出现栈溢出错误。
调试困难:递归实现的代码复杂难懂,调试起来困难,尤其是对于较深的分类树结构。
难以缓存:递归实现难以进行结果缓存,因为每次调用都会产生不同的子函数调用序列,导致缓存命中率较低。
替代方案:
为了克服递归实现的缺点,可以采用以下替代方案:
层级遍历:使用层级遍历算法,逐层遍历分类树结构,避免递归带来的栈空间消耗问题。
关联数组:将分类树结构存储在关联数组中,并使用父子关系键值进行访问,这种方式可以避免递归,并且有利于缓存。
关系数据库:将分类树结构存储在关系数据库中,并使用 SQL 查询进行查询和操作,这种方式性能稳定,并且可以利用数据库的索引和缓存机制。
建议:
对于大型或复杂无限分类的实现,建议避免使用递归,而改用上述替代方案。
3、thinkphp无限极分类
ThinkPHP无限极分类
无限极分类是一种树形结构,每个节点都可以有多个子节点,且子节点可以继续有子节点。在ThinkPHP中,可通过如下方式实现无限极分类:
1. 创建分类表
sql
CREATE TABLE `category` (
`id` INT UNSIGNED AUTO_INCREMENT,
`pid` INT UNSIGNED DEFAULT 0,
`name` VARCHAR(255) NOT NULL,
`path` VARCHAR(255) NOT NULL,
`level` TINYINT UNSIGNED NOT NULL DEFAULT 0,
`order` TINYINT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
INDEX (`pid`, `path`)
);
`id`:分类ID
`pid`:父级分类ID
`name`:分类名称
`path`:分类路径,以逗号分隔
`level`:分类层级,根节点为0
`order`:分类排序,用于同级分类顺序
2. 添加行为扩展(可选)
无限极分类的实现可以使用ThinkPHP的行为扩展来简化操作。在 `application/common/behavior/` 目录下创建 `CategoryBehavior` 文件:
```php
namespace app\common\behavior;
use Think\Behavior;
class CategoryBehavior extends Behavior
// 行为扩展执行入口
public function run(&$params)
{
// 钩子名称
$hookName = 'category_model';
if (!defined($hookName)) {
define($hookName, 1);
$this->addCategories();
}
}
protected function addCategories()
{
// 添加一个钩子,在模型初始化后触发
\think\Hook::add('model_init', function () {
if (defined('CATEGORY_MODEL')) {
return;
}
// 定义当前模型是分类模型
define('CATEGORY_MODEL', 1);
// 获取模型反射对象
$model = \think\Loader::parseName(MODULE_NAME . '/model/' . CONTROLLER_NAME);
$reflection = new \ReflectionClass($model);
// 获取模型的字段信息
$fields = $reflection->getProperty('fields')->getValue();
// 添加无限极分类字段
$fields['pid'] = ['type' => 'integer', 'default' => 0];
$fields['path'] = ['type' => 'string', 'default' => ];
$fields['level'] = ['type' => 'integer', 'default' => 0];
// 设置模型字段信息
$reflection->getProperty('fields')->setValue($fields);
});
}
```
3. 定义模型
在分类模型中,继承 `\think\Model` 并添加以下代码:
```php
class Category extends \think\Model
// 自动完成
protected $auto = [
['path', 'getPath', 'callback', self::MODEL_INSERT | self::MODEL_UPDATE, 'both'],
['level', 'getLevel', 'callback', self::MODEL_INSERT | self::MODEL_UPDATE, 'both'],
];
// 获取路径
protected function getPath()
{
return $this->pid ? $this->getParentPath() . $this->id . ',' : '0,';
}
// 获取父级路径
public function getParentPath()
{
$path = $this->pid ? $this->find($this->pid)->path : '';
return $path ? $path . $this->pid . ',' : '';
}
// 获取层级
protected function getLevel()
{
return substr_count($this->path, ',');
}
// 获取子分类
public function children()
{
return $this->hasMany('Category', 'pid');
}
// 获取父级分类
public function parent()
{
return $this->belongsTo('Category', 'pid');
}
```
4. 使用
添加分类:
```php
$category = new Category();
$category->pid = 0;
$category->name = '根分类';
$category->save();
```
获取子分类:
```php
$category->children()->select();
```
获取父级分类:
```php
$category->parent()->find();
```
修改分类:
```php
$category->name = '修改后的分类名称';
$category->save();
```
删除分类(级联删除子分类):
```php
$category->delete();
```
5. 其他操作
获取分类树:
```php
// 获取所有分类
$categories = Category::select()->order('path')->toArray();
// 构建树形结构
$tree = \think\helper\Arr::toTree($categories, 'id', 'pid', 'children');
```
移动分类:
```php
// 将分类1移动到分类2下
$category1 = Category::get(1);
$category2 = Category::get(2);
$category1->pid = $category2->id;
$category1->path = $category2->path . $category1->id . ',';
$category1->save();
```
提升分类:
```php
// 将分类1提升到与分类2同级
$category1 = Category::get(1);
$category2 = Category::get(2);
$category1->pid = $category2->pid;
$category1->path = $category2->getParentPath() . $category1->id . ',';
$category1->save();
```
4、php实现无限极分类功能
PHP 无限极分类功能实现
实现无限极分类功能,可以采用递归算法,通过递归遍历父类和子类的关系,构建出整个分类树形结构。
1. 数据模型
在数据库中,无限极分类通常使用 `id`、`parent_id` 和 `level` 三个字段来表示:
`id`: 分类 id
`parent_id`: 父类 id
`level`: 分类层级,根类目为 0
2. 分类表
```sql
CREATE TABLE categories (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
parent_id INT NOT NULL DEFAULT 0,
level INT NOT NULL DEFAULT 0,
PRIMARY KEY (id),
INDEX (parent_id),
INDEX (level)
);
```
3. 递归函数
`getCategorisTree()` 函数用于递归获取分类树:
```php
function getCategoriesTree($parentId = 0, $level = 0)
$categories = Category::where('parent_id', $parentId)->get();
foreach ($categories as $category) {
$category->level = $level;
$category->children = getCategoriesTree($category->id, $level + 1);
}
return $categories;
```
4. 使用示例
```php
$categories = getCategoriesTree();
```
5. 输出树形结构
```php
foreach ($categories as $category) {
echo str_repeat('-', $category->level) . $category->name . PHP_EOL;
```
示例输出:
```
- 根类目
-- 子类目 1
--- 子类目 1-1
--- 子类目 1-2
-- 子类目 2
--- 子类目 2-1
```