Thursday, 30 August 2018

PHP recursion with associative array (menu structure)


I've been banging my head against a wall today. I have a mysql table that has a list of menu items which have a recursive parent/child relationship. I need to create an associative array that matches it.


MySQL Database
CREATE TABLE IF NOT EXISTS `menus` (
  `sectionid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parentid` int(10) unsigned NOT NULL DEFAULT '0',
  `name` varchar(128) NOT NULL DEFAULT '',
  PRIMARY KEY (`sectionid`)
);

INSERT INTO `menus` (`sectionid`, `parentid`, `name`) VALUES
(1, 0,'DOWNLOADS'),(4, 1,'Player Scenarios'),
(5, 1,'Co Op Scenarios'),(9, 1,'MAPS');

PHP CODE

function get_db_children($parentid) {

  $mysqli = mysqli_open();
  $sqlStr = "select sectionid as childid from menus where parentid=$parentid order by sectionid";
  $result = $mysqli->query($sqlStr);
  $mysqli->close();

  return $result;

}

function get_children(&$node) {

  foreach ($node as $key=>$value) {
    $result = get_db_children($key);
    while ($row = $result->fetch_assoc()) {
       $tmp = array($row['childid'] => array());
       $node[$key][$row['childid']]= get_children($tmp);
    }
  }
  return $node;
}

===========================================
The above functions are called from my main script as follows:
$categories[0] = array ();
get_children($categories);
print "Categories=".print_r($categories);
exit;

==============
My PROBLEM.
My problem is that the structure of the returned array is not QUITE how I want it.
The code above returns:
Categories=
Array ( [0] => Array
        ( [1] => Array
          ( [1] => Array
            ( [4] => Array
              ( [4] => Array ( ) )
              [5] => Array
              ( [5] => Array ( ) )
              [9] => Array
              ( [9] => Array ( ) )
            )
          )
        )
      )

What I want is:
Categories=
Array ( [0] => Array
          ( [1] => Array
            (
              ( [4] => Array ( ) )
              ( [5] => Array ( ) )
              ( [9] => Array ( ) )
            )
          )
      )

A null array indicates no children.
I can't figure out how to get rid of the double up on key values. :(
If anyone can help, would be much appreciated.
Cheers, Nap

Changing the approach a little has fixed my problem. Instead of passing the $categories array by reference, I just pass the ID of the parent menu item and return the array.
Code below uses same SQL data and SQL accessor function get_db_children($parentid)as given in my OP. I'm sure this could be improved upon, but at least I've got my result.
@Josh, thnx for your input.
PHP Functions
function get_twigs($nodeid) {

  $result = get_db_children($nodeid);
  if ($result->num_rows != 0) {
    while ($row = $result->fetch_assoc()) {
      $node[$row['childid']] = array();
      $node[$row['childid']] = get_twigs($row['childid']);
    }
  } else {
    $node=NULL; // or any other 'no children below me indicator.
  }
  return $node;
}

function get_branch($nodeid) {

  $node[$nodeid] = array();
  $node[$nodeid] = get_twigs($nodeid);
  return $node;
}

PHP Caller
$categories = get_branch(0);

Finally got it going.

0 comments:

Post a Comment