繁体   English   中英

MySQL / PHP-多层类别结构

[英]MySQL / PHP - Multi tier category structure

我正在建立一个包含产品数据库的网站。 每个产品都属于一个类别。 类别的结构是多层的,可以包含任意数量的层,例如:

  • 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的框架。

我想做的是:

  1. 对于任何类别级别,请获取“主”父级。 Shirts这将是Fashion
  2. 对于任何类别级别,获取层中所有“最后”级别的类别。 即对于Mens来说,这将是Long SleevedShort Sleeved
  3. (更高级)对于任何类别级别,请找出其拥有的孩子/父母人数。

我的模型中具有以下默认关系:

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;
}

但是这里有很多重复,而且看起来很丑。 但是,这也使我相信也许我采用了错误的方法,并且需要重组数据库本身?

Bill我想我已经在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; 模型类中的变量。 现在调用如下函数。

  1. 获取父类别self::getSubCategories(NULL)所有self::getSubCategories(NULL)
  2. 要使所有子级都达到第二级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; 模型类中的变量。 现在调用如下函数。

  1. 要获取所有父类别self的子代:: getParentCategories(16,0)
  2. 要使所有孩子都达到第二级自我:: getParentCategories(16,2)

您可以使用自己的班级名称代替self

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM