Build recursive nested menu from array

后端 未结 3 1738
野性不改
野性不改 2021-01-23 03:09

I\'m trying to build a recursive menu which would look something like this when finished, with an infinite amount of nested items:



        
3条回答
  •  不思量自难忘°
    2021-01-23 03:50

    I would index all the menu items (pages) by id first. In the second loop associate menu items with their parents and keep track of top level items.

    One of the ways I would do it (Render method is just an example):

    $sqlGetDropdownPages = "SELECT * FROM `cms_staticPages` ORDER BY `sortOrder` ASC";
    $qryGetDropdownPages = mysql_query($sqlGetDropdownPages) or die(mysql_error());
    
    //indexing pages by id
    while ($pageRow = mysql_fetch_assoc($qryGetDropdownPages)) {
        $menuItems[$pageRow['id']] = new MenuItem($pageRow);
    }
    
    //associating pages with parents
    foreach ($menuItems as $menuItem) {
        if ($menuItem->hasParent()) {
            $menuItem->addToParent($menuItems);
        } else {
            $topLevel[] = $menuItem;
        }
    }
    
    //$topLevel is an array of menuItems without parents
    $render = '
      '; foreach ($topLevel as $menuItem) { $render .= $menuItem->render(true); } $render .= '
    ';

    MenuItem class would look something like this

    class MenuItem {
    
        /**
         * @var array
         */
        private $data;
    
        /**
         * @var MenuItem[]
         */
        private $children = array();
    
        /**
         * @var MenuItem
         */
        private $parent;
    
        /**
         * @param array $data
         */
        public function __construct($data) {
            $this->data = $data;
        }
    
        /**
         * Finds the parent in the collection and adds itself to it
         * @param MenuItem[] $menuItems
         */
        public function addToParent($menuItems) {
            if (isset($menuItems[$this->data['parent_id']])) {
                $this->parent = $menuItems[$this->data['parent_id']];
                $this->parent->addChild($this);
            }
        }
    
        /**
         * @return bool
         */
        public function hasParent() {
            return empty($this->data['parent_id']);
        }
    
        /**
         * @param MenuItem $child
         */
        public function addChild(MenuItem $child) {
            $this->children[] = $child;
        }
    
        /**
         * Renders the menu with ul li
         * @param bool $withChildren
         * @return string
         */
        public function render($withChildren = false) {
            $render = '
  • ' . $this->data['identifier'] . '
  • '; if ($withChildren) { $render .= '
      '; foreach ($this->children as $child) { $render .= $child->render(true); } $render .= '
    '; } return $render; } }

提交回复
热议问题