温馨提示:本文翻译自stackoverflow.com,查看原文请点击:recursion - Recursive function issue in PHP overwrites result when going to a new child in breadth
php recursion

recursion - PHP中的递归函数问题会导致广度转向新孩子时覆盖结果

发布于 2020-03-29 21:30:09

我的数据库结构如下:

+----+-----------+-----------+
| ID |   Name    | Parent_ID |
+----+-----------+-----------+
|  1 | 123a      | 2         |
|  2 | Microsoft | 3         |
|  3 | Apple     | 14        |
|  5 | IBM       | 14        |
| 14 | Amazon    | NULL      |
+----+-----------+-----------+

我想检索具有特定ID的所有子代的数组。

因此,如果我启动ID = 14的函数,我想得到以下结果:

array (size=2)
  0 => 
    array (size=3)
      'orgid' => string '3' (length=1)
      'name' => string 'Apple' (length=5)
      'parent_id' => string '14' (length=1)
  1 => 
    array (size=3)
      'orgid' => string '5' (length=1)
      'name' => string 'IBM' (length=3)
      'parent_id' => string '14' (length=2)

这是我到目前为止的代码:

    function get_all_children_from_tree($orgparentid, $childrenArray = null)
    {
        $CI = get_instance();
        $CI->load->model('organization/organization_model');

        $allChildrenOrgs = $CI->organization_model->getAllChildrenForParent($orgparentid);
        if (empty($childrenArray)) {
            $childrenArray = [];
        }

        foreach ($allChildrenOrgs as $org)
        {
            $org_id = $org->org_id;
            $org_name = $org->name;
            $org_parent_id = $org->parent_id;
            $arr = array('orgid' => $org_id, 'name' => $org_name, 'parent_id' => $org_parent_id);
            array_push($childrenArray, $arr);

            if (!empty($org_id)) {
                get_all_children_from_tree($org_id, $childrenArray);
            }
        }
        return $childrenArray;
    }

在第一个子节点上进行深度学习非常有用,并且可以为我提供正确的结果,但是,一旦我输入了根节点的第二个子节点(在此示例中为IBM),结果数组将在递归点处返回其原始值函数被调用。因此,所有孩子都被结果驱逐出境。

例如,上面提供的代码和示例数据的结果将是:

array (size=5)
  0 => 
    array (size=3)
      'orgid' => string '14' (length=1)
      'name' => string 'Amazon' (length=6)
      'parent_id' => NULL
  4 => 
    array (size=3)
      'orgid' => string '5' (length=1)
      'name' => string 'IBM' (length=3)
      'parent_id' => string '14' (length=2)

查看更多

提问者
Dennis
被浏览
28
Tim Biegeleisen 2020-01-31 18:12

如果您使用的是MySQL 8+,则可以使用递归分层CTE在数据库上完全解决此问题:

WITH RECURSIVE cte (id, name, parent_id) AS (
    SELECT ID, Name, Parent_ID
    FROM yourTable
    WHERE ID = 14
    UNION ALL
    SELECT t1.ID, t1.Name, t1.Parent_ID
    FROM yourTable t1
    INNER JOIN cte t2 ON t1.Parent_ID = t2.ID
)

SELECT * FROM cte;

还有一些方法可以在早期版本的MySQL上执行此操作,尽管在任何情况下我都建议您在数据库本身而不是PHP上进行处理。