【问题标题】:Find all child and grandchild nodes from given parent id PHP从给定的父 ID PHP 中查找所有子节点和孙节点
【发布时间】:2016-09-21 22:40:13
【问题描述】:

我在推荐系统中工作。 假设用户A邀请用户B和用户C。然后用户B邀请用户D,用户C邀请用户E等等。如何遍历所有子节点和孙节点?

这是我的数据库中的示例数据

ID       name       referral_id
1        user A     null//assume the tree starts from here
2        user B     1
3        user C     1
4        user D     2
5        user E     3

如何创建一个函数来检索用户 A 作为父节点,然后列出用户 B(带有子节点 D)和用户 C(带有子节点 E)??

我正在使用 CI,这是我从父 id 检索 2 个子节点的查询

$downline_query = $this->db->query("SELECT * FROM user WHERE referral_id = '1'")
//above query will return user B and C as result.. hardcoded for example

$downline = array();
foreach($downline_query as $result){
   $downline[] = array( 
       "name" => $result['name'],
       "id"   => $result['id']
   );
}
//above $downline array will only contain user B and C. I don't know where to go again after this step.. 

$records = array("data"=>$downline);
echo json_encode($records);

这一步之后我不知道该去哪里.. 已经完成了几种类型的算法,包括 while 循环和 foreach 循环。但它仍然不是那么“动态”。

请注意,我只需要所有子孙的姓名和 ID。它不必是多维数组。只要我能得到所有的孩子和孙子和曾孙子就可以了..

我打算将所有的子孙等保存到 $downline 数组中。所以所有的都将在一个没有多维数组的数组中

真的需要关于如何做到这一点的指导。以前从未做过这种层次结构的事情。谢谢:)

【问题讨论】:

  • 对于这种结构查询..看看mikehillyer.com/articles/managing-hierarchical-data-in-mysql..这个链接很有用。
  • 请查看此链接问题我的帮助。 For Create Tree
  • 单个循环无法解决此问题,您必须在尝试组织它们之前访问所有数据,否则如果它们出现故障,您会错过一些数据。在第一个循环中,您必须按 ID 对它们进行排序,最好将其作为键,然后在第二个循环中,您通过按 ID/KEY 从第一个数组中提取关联数据来构建第二个数组,

标签: php


【解决方案1】:

这应该可以,假设$downline_query 包含您需要的所有行。 IE 1 数据库查询。

$affilites = [];
$parents = []
foreach($downline_query as $row){
   if( $row['referral_id'] ){
       if( !isset(  $affilites[$row['referral_id']] ) ){
             $affilites[$row['referral_id']] = [];
       }
       $affilites[$row['referral_id']][] = $row;
   }else{
       $parents[$row['id']] = $row;
   }
}
// you now have 2 arrays 1 of parents, one of children. now just combine ( shown below )
$parent = [
    1 => ['ID'=>1,'name'=>'user A', 'referral_id' =>null],  
];

$affiliate = [
    1 => [
            ['ID'=>2,'name'=>'user B', 'referral_id' =>1],
            ['ID'=>3,'name'=>'user C', 'referral_id' =>1],
        ],
    2 => [['ID'=>4,'name'=>'user D', 'referral_id' =>2]],
    3 => [['ID'=>5,'name'=>'user E', 'referral_id' =>3]],
    5 => [['ID'=>16,'name'=>'user F', 'referral_id' =>5]],
];


print_r(getparents( $parent, $affiliate));

function getparents( $parent, $affiliate ){
    $result = [];
    foreach ($parent as $row ){
        $id = $row['ID'];

        $result[] = $row;

        if( isset($affiliate[$id]) ){
         //no children
            $result[$id]['children'] = getparents( $affiliate[$id], $affiliate ); //recurse
        }
    }
    return $result;
}

以及最终的输出

 Array(
        [0] => Array(
                [ID] => 1
                [name] => user A
                [referral_id] =>
                [children] => Array(
                        [0] => Array(
                                [ID] => 2
                                [name] => user B
                                [referral_id] => 1
                                [children] => Array(
                                        [0] => Array(
                                                [ID] => 4
                                                [name] => user D
                                                [referral_id] => 2
                                                )

                                        )

                                )

                        [1] => Array(
                                [ID] => 3
                                [name] => user C
                                [referral_id] => 1
                                [children] => Array(
                                        [0] => Array(
                                                [ID] => 5
                                                [name] => user E
                                                [referral_id] => 3
                                                [children] => Array(
                                                        [0] => Array(
                                                                [ID] => 16
                                                                [name] => user F
                                                                [referral_id] => 5
                                                                )

                                                        )

                                                )

                                        )

                                )

                        )

                )

        ) 

【讨论】:

  • 先生,它会继续从子节点迭代到所有孙节点吗?
  • 不,它只会工作一层,你必须让它递归才能做到这一点。但是在这种情况下,最好使用嵌套集或物化路径。因为那样你就有了层次结构而不是父子关系。
  • @Vinfoster0701 - 请查看我的更新答案,该答案现在是递归的,
【解决方案2】:

你可以试试递归函数:

function get_referrals ($referral_id){
    $downline = array();
    $downline_query = $this->db->query("SELECT * FROM user WHERE referral_id = '$referral_id'");
    foreach($downline_query as $result){
       $downline[] = array(
           "name" => $result['name'],
           "id"   => $result['id']
       );
       $downline['invited'] = get_referrals($result['id']);  # <--- recursive !!!
    }
    return $downline;
}

并获得您的 $downline

$downline = get_referrals(1);


print_r($downline);

【讨论】:

  • 我建议使用准备好的语句,因为您的答案容易受到 sql 注入的影响,即get_referrals("'; DROP TABLE users; --");
  • 这只是一个解决方案......不是最终代码。实施应由开发人员 Vinfoster0701 完成。它将产生所需的结果。
猜你喜欢
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 2011-08-10
  • 2016-03-11
  • 1970-01-01
相关资源
最近更新 更多