我正在构建一个包含产品数据库的网站。每个产品属于一个类别。类别的结构是多层的,可以包含任意数量的层,例如:
Electronics
> Games Consoles
> Xbox
> Xbox One
> Games
> etc..
Fashion
> Mens
> Shirts
> Long Sleeved
我总是将产品分配到层中的“最后”类别。
以下是我的类别表的结构:
id name parent_id
================================
1 Fashion NULL
2 Mens 1
3 Shirts 2
4 Long Sleeved 3
5 Short Sleeved 3
我正在使用Yii2作为我的应用程序框架,但相同的概念应该适用于大多数MVC框架,或者至少应用于实现像ActiveRecord这样的ORM的那些。
我想做的是:
Shirts
,它将是Fashion
Mens
,它将是Long Sleeved
和Short Sleeved
。我的模型中有以下默认关系:
public function getParent()
{
return $this->hasOne(Category::className(), ['id' => 'parent_id']);
}
public function getParent()
{
return $this->hasMany(Category::className(), ['parent_id' => 'id']);
}
以下是我创建的函数,它输出任何给定类别的“树”:
public function getParentTree()
{
$array = [];
// $this->parent refers to the 'getParent()' relation above
if(!empty($this->parent))
{
$array[] = $this->parent->name;
if(!empty($this->parent->parent))
$array[] = $this->parent->parent->name;
if(!empty($this->parent->parent->parent))
$array[] = $this->parent->parent->parent->name;
}
else
$array[] = "(none)";
$output = implode(" --> ", array_reverse($array));
return $output;
}
但这里有很多重复,看起来很难看。但它也让我相信也许我采取了错误的方法并需要重组数据库本身?
答案 0 :(得分:0)
比尔我想我已经在YII2中解决了这个问题 - >模型。
以下是我的代码。
public static function getSubCategories($parent_id = NULL, $level = 0)
{
// Get the Category from table
// Here you can use caching Yii::$app->cache->get to avoid multiple queries
$categories = Category::find()->select(['id', 'parent_id', 'name'])->where(['parent_id' => $parent_id])->asArray()->all();
// Logic of Nth level to return
self::$max_down_level += 1;
if($level != 0 && self::$max_down_level > $level) return $categories;
// Now for each sub categories find and return chidren as Array
foreach($categories as $key => $category)
{
$categories[$key]['children'] = self::getSubCategories($category['id'], $level);
}
return $categories;
}
另外,不要忘记在模型类中声明public static $max_down_level = 0;
变量。现在调用下面的函数。
self::getSubCategories(NULL)
self::getSubCategories(NULL, 2)
同样,您可以声明递归函数以获取父类别。
public static function getParentCategories($parent_id, $level = 0)
{
// Get the Category from table
// Here you can use caching Yii::$app->cache->get to avoid multiple queries
$categories = Category::find()->select(['id', 'parent_id', 'name'])->where(['id' => $parent_id])->asArray()->all();
// Logic of Nth level to return
self::$max_up_level += 1;
if($level != 0 && self::$max_up_level > $level) return $categories;
foreach($categories as $key => $category)
{
$categories[$key]['parent'] = self::getParentCategories($category['parent_id'], $level);
}
return $categories;
}
另外,不要忘记在模型类中声明public static $max_up_level = 0;
变量。现在调用下面的函数。
您可以使用自己的班级名称代替self
希望这有帮助。