0

I know this is asked a lot, but I can't get it to work correctly.

What I have A PHP function that get's the page id (fk_page). Inside this function the same function is called to look for child pages.

My Database looks like this:

enter image description here

The PHP Code looks like this:

private function createNav($parent = 0, $sub = false) {
        // *!* Create Nav
        $getNavPage = $this->model->loadNav($parent); // array of menu items (fk_page) that have $parent as parent.

        $NavPage = 0;
        foreach ($getNavPage as $getPage) {

            $NavPage = intval($getPage["fk_page"]);

            $subnav = $this->createNav($NavPage, true); // get childs (recursive loop) and save fk_page in $subnav

            if($sub === false) $this->navArr[$parent][] = $NavPage;
            else $this->navArr[$parent][][] = $NavPage;
        }

        return $NavPage;
}

The model does the following

public function loadNav($parent) {
    $stmt = $this->pdo->prepare("SELECT fk_page FROM nav WHERE fk_parentpage = " . $parent . ";");
            $stmt->execute();
    return $stmt->fetchAll();
}

Now the result is an array that looks like this

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [2]=>
  array(1) {
    [0]=>
    array(1) {
      [0]=>
      int(4)
    }
  }
  [3]=>
  array(2) {
    [0]=>
    array(1) {
      [0]=>
      int(5)
    }
    [1]=>
    array(1) {
      [0]=>
      int(6)
    }
  }
}

What I would like to have as a result:

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
      array(1) {
        [0]=>
        array(1) {
          [0]=>
          int(4)
        }
    }
    [3]=>
      array(2) {
        [0]=>
        array(1) {
          [0]=>
          int(5)
        }
        [1]=>
        array(1) {
          [0]=>
          int(6)
        }
      }
  }
}

I believe that the createNav() must run before the array element is written (or even inside the array $this->NavArr), but I wasn't really succesfull.

3
  • So, in your database, you have ID, Name, Parent ID ? Commented Aug 29, 2017 at 14:07
  • @BrianGottier Updated the question with the DB. fk = foreign key Commented Aug 29, 2017 at 14:14
  • I have my own way of doing what you're doing, but they're not so similar, and too much code for a comment. Even still, even if you don't have exactly ID, Name, and Parent ID, you still have the concept of the parent to child hierarchy. Maybe this can help: gist.github.com/anonymous/f4e5f1b1dd4878e394ec0ef2322e4cc4 Commented Aug 29, 2017 at 14:25

1 Answer 1

1

Here is an example that uses local data but mimics what you're trying to do:

$data_array = array(
    0 => array(1, 2, 3)
    , 2 => array(4)
    , 3 => array(5, 6)
);

function get_kids($id = 0) {
    global $data_array;
    if(isset($data_array[$id])) {
        return $data_array[$id];
    }
    else {
        return array();
    }
}

function create_navigation($parent_id = 0) {

    // Check for children
    $children_array = get_kids($parent_id);

    // No children - just return the parent
    if (empty($children_array)) {
        return $parent_id;
    }

    // Children!
    foreach ($children_array as $key => $child_id) {
        $children_array[$key] = create_navigation($child_id);
    }

    return array($parent_id => $children_array);
}

echo '<pre>';
    $nav = create_navigation(0);
    var_dump($nav);
    print_r($nav);
echo '</pre>';

The $data_array is used instead of your database.

The get_kids function is your loadNav method.

The create_navigation function is your createNav method.

This produces a var_dump:

array(1) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    array(1) {
      [2]=>
      array(1) {
        [0]=>
        int(4)
      }
    }
    [2]=>
    array(1) {
      [3]=>
      array(2) {
        [0]=>
        int(5)
        [1]=>
        int(6)
      }
    }
  }
}

And a print_r:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => Array
                (
                    [2] => Array
                        (
                            [0] => 4
                        )

                )

            [2] => Array
                (
                    [3] => Array
                        (
                            [0] => 5
                            [1] => 6
                        )

                )

        )

)

The problem with your original code is you were assigning IDs to the class variable $this->navArr instead of using recursion to return the child elements ($subnav).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I this worked and I think I begin to understand why... I try to document every step, what it does exactly because this is hard for me to imagine and explain. That's why I do stupid logic mistakes...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.