PHP:递归获取父级的子级

发布于 2024-08-23 02:50:16 字数 770 浏览 12 评论 0原文

我有一个函数可以从我的数据库中获取父级的所有子级的 id。因此,如果我查找 id 7,它可能会返回一个包含 5、6 和 10 的数组。然后我想做的是递归查找这些返回 id 的子级,依此类推,直到子级的最终深度。

我尝试编写一个函数来执行此操作,但我对递归感到困惑。

function getChildren($parent_id) {
    $tree = Array();
    $tree_string;
    if (!empty($parent_id)) {
        // getOneLevel() returns a one-dimentional array of child ids
        $tree = $this->getOneLevel($parent_id);
        foreach ($tree as $key => $val) {
            $ids = $this->getChildren($val);
            array_push($tree, $ids);
            //$tree[] = $this->getChildren($val);
            $tree_string .= implode(',', $tree);
        }

        return $tree_string;
    } else {
        return $tree;
    }

}//end getChildren()

函数运行后,我希望它返回找到的所有子 ID 的一维数组。

I have a function which gets the ids of all children of a parent from my DB. So, if I looked up id 7, it might return an array with 5, 6 and 10. What I then want to do, is recursively find the children of those returned ids, and so on, to the final depth of the children.

I have tried to write a function to do this, but I am getting confused about recursion.

function getChildren($parent_id) {
    $tree = Array();
    $tree_string;
    if (!empty($parent_id)) {
        // getOneLevel() returns a one-dimentional array of child ids
        $tree = $this->getOneLevel($parent_id);
        foreach ($tree as $key => $val) {
            $ids = $this->getChildren($val);
            array_push($tree, $ids);
            //$tree[] = $this->getChildren($val);
            $tree_string .= implode(',', $tree);
        }

        return $tree_string;
    } else {
        return $tree;
    }

}//end getChildren()

After the function is run, I would like it to return a one-dimentional array of all the child ids that were found.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笔落惊风雨 2024-08-30 02:50:17

而不是 array_push($tree, $ids); 尝试 $tree = array_merge($tree, $ids);。杀死 $tree_string .= implode(',', $tree);返回 $tree。 (一次)

function getChildren($parent_id) {
    $tree = Array();
    if (!empty($parent_id)) {
        $tree = $this->getOneLevel($parent_id);
        foreach ($tree as $key => $val) {
            $ids = $this->getChildren($val);
            a$tree = array_merge($tree, $ids);
        }
    }
    return $tree;
}

Rather than array_push($tree, $ids); try $tree = array_merge($tree, $ids);. Kill the $tree_string .= implode(',', $tree); and just return $tree. (Once)

function getChildren($parent_id) {
    $tree = Array();
    if (!empty($parent_id)) {
        $tree = $this->getOneLevel($parent_id);
        foreach ($tree as $key => $val) {
            $ids = $this->getChildren($val);
            a$tree = array_merge($tree, $ids);
        }
    }
    return $tree;
}
昨迟人 2024-08-30 02:50:17

我可以向您推荐这个有效的版本:

public function getDescendants($id){
    $sth = $this->db->prepare(
        "YOUR SQL"
    );
    $sth->execute([$id]);
    $descendants = $sth->fetchAll(PDO::FETCH_ASSOC);

    // Recursively repeat the query for each id
    return array_reduce($descendants, function($carried_array, $father){
        // Spread operator to merge arrays [...carried_array, father, ...descendants]
        return [...$carried_array, $father, ...$this->getDescendants($father['id'])];
    }, []);
}

I can suggest you this version that works:

public function getDescendants($id){
    $sth = $this->db->prepare(
        "YOUR SQL"
    );
    $sth->execute([$id]);
    $descendants = $sth->fetchAll(PDO::FETCH_ASSOC);

    // Recursively repeat the query for each id
    return array_reduce($descendants, function($carried_array, $father){
        // Spread operator to merge arrays [...carried_array, father, ...descendants]
        return [...$carried_array, $father, ...$this->getDescendants($father['id'])];
    }, []);
}
不醒的梦 2024-08-30 02:50:16

这对我来说效果很好:

function getOneLevel($catId){
    $query=mysql_query("SELECT categoryId FROM categories WHERE categoryMasterId='".$catId."'");
    $cat_id=array();
    if(mysql_num_rows($query)>0){
        while($result=mysql_fetch_assoc($query)){
            $cat_id[]=$result['categoryId'];
        }
    }   
    return $cat_id;
}

function getChildren($parent_id, $tree_string=array()) {
    $tree = array();
    // getOneLevel() returns a one-dimensional array of child ids        
    $tree = $this->getOneLevel($parent_id);     
    if(count($tree)>0 && is_array($tree)){      
        $tree_string=array_merge($tree_string,$tree);
    }
    foreach ($tree as $key => $val) {
        $this->getChildren($val, &$tree_string);
    }   
    return $tree_string;
}

调用 getChildren(yourid);
然后它将返回给定节点/父节点的完整子节点数组。

This work fine for me:

function getOneLevel($catId){
    $query=mysql_query("SELECT categoryId FROM categories WHERE categoryMasterId='".$catId."'");
    $cat_id=array();
    if(mysql_num_rows($query)>0){
        while($result=mysql_fetch_assoc($query)){
            $cat_id[]=$result['categoryId'];
        }
    }   
    return $cat_id;
}

function getChildren($parent_id, $tree_string=array()) {
    $tree = array();
    // getOneLevel() returns a one-dimensional array of child ids        
    $tree = $this->getOneLevel($parent_id);     
    if(count($tree)>0 && is_array($tree)){      
        $tree_string=array_merge($tree_string,$tree);
    }
    foreach ($tree as $key => $val) {
        $this->getChildren($val, &$tree_string);
    }   
    return $tree_string;
}

Call the getChildren(yourid);
Then it will return the complete array of children for that given node/parent.

土豪我们做朋友吧 2024-08-30 02:50:16

嵌套集模型而不是邻接列表模型


我可以建议您将数据库中的节点存储在 NSM 而不是 ALM 下吗?

请注意,使用 ALM(您正在使用的)获取子节点非常困难,这是可能的,但需要额外的工作。如果使用嵌套集模型,选择子节点或所有节点,甚至查找所有节点的深度都可以在单个 SQL 查询中完成。

我希望这能让您了解如何解决您的问题,如果您在项目开发方面还很年轻,那么现在切换将为您省去很多麻烦。

Nested Set Model instead of Adjacency List Model


Can I suggest that you store your nodes in your database under NSM instead of ALM?

Notice that with ALM, (which is what you are using) getting the children nodes is quite difficult, its possible, but requires extra work. If you use nested set model selecting a child node, or all nodes, or even finding the depth of all nodes can be done in a single SQL query.

I hope this sheds some light on how you could solve your problem, if you are still young in the development of your project switching now will save you a lot of headaches later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文