简体   繁体   中英

PHP Hierarchical Array - Parents and Children

I am creating a Parent - Children Hierarchy Array. Please find below the array and help me in fixing.

It is working fine when parent_id is in sequence but I want to keep my array values same.

function Testing()
{
    $tasks[] = array("id" => 1, "parent_id" => 0);
    $tasks[] = array("id" => 2, "parent_id" => 5);
    $tasks[] = array("id" => 3, "parent_id" => 2);
    $tasks[] = array("id" => 5, "parent_id" => 3);
    $tasks[] = array("id" => 4, "parent_id" => 3);
    $tasks[] = array("id" => 6, "parent_id" => 5);
    $tasks[] = array("id" => 7, "parent_id" => 6);

    $tree = buildTree($tasks);
    print("<pre>");print_r($tree);
}

function buildTree(array $elements, $parentId = 0) {
    $branch = array();

    foreach ($elements as $element) {
        if ($element['parent_id'] == $parentId) {
            $children = buildTree($elements, $element['id']);
            if ($children) {
                $element['children'] = $children;
            }
            $branch[] = $element;
        }
    }

    return $branch;
}

Expected Output

Array
(
    [0] => Array
        (
            [id] => 1
            [parent_id] => 0
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 2
                            [parent_id] => 1
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 3
                                            [parent_id] => 2
                                            [children] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [id] => 5
                                                            [parent_id] => 3
                                                            [children] => Array
                                                                (
                                                                    [0] => Array
                                                                        (
                                                                            [id] => 6
                                                                            [parent_id] => 5
                                                                            [children] => Array
                                                                                (
                                                                                    [0] => Array
                                                                                        (
                                                                                            [id] => 7
                                                                                            [parent_id] => 6
                                                                                        )

                                                                                )

                                                                        )

                                                                )

                                                        )

                                                    [1] => Array
                                                        (
                                                            [id] => 4
                                                            [parent_id] => 3
                                                        )

                                                )

                                        )

                                )

                        )

                )

        )

)

To avoid an error with an infinite loop, when some element has a parent_id from their children, you could take a third parameter to list all ids already managed. And if a id come back in your treatment, you could throw an Exception:

function buildTree(array $elements, $parentId = 0, $managedParent = []) {
    $branch = array();

    // Add new id in list of managed ids
    $managedParent[] =$parentId;

    foreach ($elements as $element) {

        if ($element['parent_id'] == $parentId) {

          // check id not already managed
          if(in_array($element['id'], $managedParent))
          {
            // in this case children are already a parent of same structure. Throw an Excpetion
            throw new \Exception('Invalid structure given');
          }

          $children = buildTree($elements, $element['id'], $managedParent);
          if ($children) {
              $element['children'] = $children;
          }
          $branch[] = $element;
        }
    }

    return $branch;
}

EDIT:

Live example here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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