递归获取类别树(Yii)

lb3vh1jj  于 2022-11-09  发布在  其他
关注(0)|答案(4)|浏览(106)

我有一个具有以下结构的表:
类别

  • 标识符
  • 姓名
  • 父标识

我想得到一个功能单一的分类树,我在我的模型中写了类似的东西,但是它不起作用。

public function getChildren($parent) { 
        $criteria = new CDbCriteria;
        $criteria->condition='parent_id=:id';
        $criteria->params=array(':id'=>$parent);
        $model = Term::model()->findAll($criteria);
        while ($model) {
            echo $model->id . "<br />";
            $this->getChildren;
        }
}

有人能帮我吗?谢谢。

nhaq1z21

nhaq1z211#

我终于解决了这个问题。如果有人感兴趣,这里的代码:

public function getChildren($parent, $level=0) { 
        $criteria = new CDbCriteria;
        $criteria->condition='parent_id=:id';
        $criteria->params=array(':id'=>$parent);
        $model = $this->findAll($criteria);
        foreach ($model as $key) {
            echo str_repeat(' — ', $level) . $key->name . "<br />";
            $this->getChildren($key->id, $level+1);
        }
    }
public function getChildrenString($parent) { 
        $criteria = new CDbCriteria;
        $criteria->condition='parent_id=:id';
        $criteria->params=array(':id'=>$parent);
        $model = $this->findAll($criteria);
        foreach ($model as $key) {
            $storage .= $key->id . ","; 
            $storage .= $this->getChildrenString($key->id);
        }
        return $storage;
    }
1wnzp6jl

1wnzp6jl2#

这是一个更好的解决方案。每个级别只有一个查询。其他解决方案使用每个子级的查询或查询所有记录(如果数量较少,则效果较好)

$models=Category::find()->where(['id'=>4])->one()->getRecursiveChildren();

public function getChild()
{
    return $this->hasMany(Category::className(), ['parent_id' => 'id']);
}
public function getRecursiveChildren()
{
    $models=[];
    $childs=$this->child;
    Yii::createObject(ActiveQuery::className(), [get_called_class()])->findWith(['child'], $childs);
    if(is_array($childs)&&count($childs)>0)
        foreach ($childs as $item)
        {
            $models[]=$item;
            $models=array_merge($models,$item->getRecursiveChildren());
        }
    return $models;
}
lvmkulzt

lvmkulzt3#

您可以在模型中使用一个递归函数来实现,如下所示:

public function getCategoriesTree(&$tree = array(), $parentID = 0)
{
    $criteria = new CDbCriteria;
    $criteria->condition='parent_id=:id';
    $criteria->params=array(':id'=>$parentID);
    $resultNumber = $this->count($criteria);

    if($resultNumber > 0)
    {
        $model = $this->findAll($criteria);
        // get category position as order_id
        $orderId = 0;
        foreach ($model as $key) 
        {
            $tree[$orderId] = array(
                'id' => $key->id,
                'parent_id' => $key->parent_id,
                'name' => $key->name,
            );

            // get subcategories
            $this->getCategoriesTree($tree[$orderId]['subcat'], $key->id);

            if(count($tree[$orderId]['subcat']) === 0)
            {
                unset($tree[$orderId]['subcat']);
            }

            $orderId++;
        }
    }
}

并在控制器中将其用作:

$model = new Categories;

    $tree = array(
        0 => array(
            'id' => 0,
            'parent_id' => -1,
            'name' => 'Main category',
            'subcat' => array()
        ),
    );

    $model->getCategoriesTree($tree[0]['subcat']);
mbyulnm0

mbyulnm04#

可能是这一个帮助你...:)
我正在为类别yii2复制我的控制器类

<?php
namespace api\modules\v1\controllers;

use Yii;
use yii\rest\Controller;
use api\modules\v1\models\MySearializer;
use api\modules\v1\models\search\CategorySearch;
use api\modules\v1\models\Category;

class CategoryController extends Controller
{
    public function actionIndex()
    {
        $searchModel = new CategorySearch();
        $status        = false;
        $message       = '';
        $data          = (object)[];

        $dataProvider = $searchModel->search(Yii::$app->request->getBodyParams());
        $obj = new MySearializer();
        $obj->collectionEnvelope ='pager';
        $ser = $obj->serialize($dataProvider);
        return ['status' => true, 'message' => 'Category Listing', 
        'data' => $ser];
    }

    public function actionView($id)
    {
        $status        = false;
        $message       = '';
        $data          = (object)[];
        $model = Category::findOne($id);
        if($model)
        {
           return ['status' => true, 'message' => 'Category View', 
        'data' => $model];
        }else
        {
            return ['status' => false, 'message' => 'Category not found', 
        'data' => $data];
        }
    }

    public function actionAllParent()
    {
        $status        = false;
        $message       = '';
        $data          = (object)[];
        $model = Category::find()->where(['parent'=>0])->all();
        if($model)
        {
           return ['status' => true, 'message' => 'All Parent Category Listing', 
        'data' => $model];
        }else
        {
            return ['status' => false, 'message' => 'Parent Category not found', 
        'data' => $data];
        }
    }

    public function actionTree()
    {
        $status        = false;
        $message       = '';
        $data          = (object)[];
        $model = Category::find()->asArray()->all();
        $cattree = $this->CreateTree($model);
        print_r($cattree); die;
        if($model)
        {
           return ['status' => true, 'message' => 'All Child Category Listing', 
        'data' => $model];
        }else
        {
            return ['status' => false, 'message' => 'Child Category not found', 
        'data' => $data];
        }
    }

    public function actionChild($id)
    {
        $status        = false;
        $message       = '';
        $data          = (object)[];
        $model = Category::find()->where(['parent'=>$id])->all();
        if($model)
        {
           return ['status' => true, 'message' => 'All Child Category Listing', 
        'data' => $model];
        }else
        {
            return ['status' => false, 'message' => 'Child Category not found', 
        'data' => $data];
        }
    }

    public function CreateTree($tree,$parentId=0)
    {
        $branch =[] ;
        foreach ($tree as $element) 
        {
        if ($element['parent'] == $parentId) 
        {
            $children = $this->CreateTree($tree, $element['slno']);
            if ($children) 
            {
                $element['children'] = $children;
            }
            $branch[] = $element;
        }
       }
        return $branch;
    }
}

相关问题