dongrongdao8902 2014-08-19 23:40
浏览 21
已采纳

创建一个由多级结构组成的菜单,如何更有效地执行此操作? 没有硬编码限制?

I was asked to modify existing code to allow multi-level page structure. Each page can have one parent, and one page can have multiple children.

I will present following code. My question is is there a more efficient way of doing this? I am hard-coding the number of levels that are reachable.

Is there easier way to do this automatically without hard coding? Recursion perhaps?

function createMenu($parents) {
    foreach ($parents as $parent) {
        $parentName = $this->getPagefromID($parent);
        $kids = $this->areThereKids($parent);

        if ($kids == "yes") {
            echo "<ul class=\"children\">
";
            $query = "SELECT * FROM pages";
            $result = mysql_query($query) or die('Query failed: ' . mysql_error());
            while ($row = mysql_fetch_assoc($result)) {
                $thisparent = $row['Parent'];
                $name = $row['Name'];
                $id2 = $row['ID'];
                if ($thisparent == $parent) {
                    echo "<li><a href=\"edit.php?id=$id2\">" . $name . "</a></li>
";
                    if($this->areThereKids($id2) == "yes") {
                        $children = $this->getMyKids($id2);
                        foreach($children as $kid) {
                            $info = $this->getPersonInformation($kid);
                            $kidid = $info[0]["ID"];
                            echo "<li><a href=\"edit.php?id=$kidid\">" . $info[0]['Name'] . "</a></li>
";
                            // more sub
                            if($this->areThereKids($kidid) == "yes") {
                                $children1 = $this->getMyKids($kidid);
                                foreach($children1 as $kid1) {
                                    $info1 = $this->getPersonInformation($kid1);
                                    $kidid1 = $info1[0]['ID'];
                                    echo "<li><a href=\"edit.php?id=$kidid1\">-" . $info1[0]['Name'] . "</a></li>
";
                                    if($this->areThereKids($kidid1) == "yes") {
                                        $children2 = $this->getMyKids($kidid1);
                                        foreach($children2 as $kid2) {
                                            $info2 = $this->getPersonInformation($kid2);
                                            $kidid2 = $info2[0]['ID'];
                                            echo "<li><a href=\"edit.php?id=$kidid2\">--" . $info2[0]['Name'] . "</a></li>
";
                                            // No need for 6 levels.
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            echo "</ul>
";
        }
        echo "</li>
";
    }
}
  • 写回答

1条回答 默认 最新

  • du8791069 2014-08-21 14:01
    关注

    This would be more efficiently done with recursion.

    Identify the steps of the code that are repeated and turn them into a subroutine. From your code, we have the following repeated unit:

    (...)
        if($this->areThereKids($id2) == "yes") {
            $children = $this->getMyKids($id2);
            foreach($children as $kid) {
                $info = $this->getPersonInformation($kid);
                $kidid = $info[0]["ID"];
                echo "<li><a href=\"edit.php?id=$kidid\">" . $info[0]['Name'] . "</a></li>
    ";
                // more sub
                if($this->areThereKids($kidid) == "yes") {
    (...)
    

    Turn that into a function (assuming you're working with an object):

    function dealWithKids($par) {
        if ($this->areThereKids($par) == 'yes') {
            $children = $this->getMyKids($par);
            foreach ($children as $kid) {
                $info = $this->getPersonInformation($kid);
                $kidid = $info[0]["ID"];
                echo "<li><a href=\"edit.php?id=$kidid\">" . $info[0]['Name'] . "</a></li>
    ";
                // instead of repeating the same steps again,
                // call the dealWithKids function here
                $this->dealWithKids($kidid);
            }
        }
    }
    

    ...and then call that function instead of the repeated units of code:

            while ($row = mysql_fetch_assoc($result)) {
                $thisparent = $row['Parent'];
                $name = $row['Name'];
                $id2 = $row['ID'];
                if ($thisparent == $parent) {
                    echo "<li><a href=\"edit.php?id=$id2\">" . $name . "</a></li>
    ";
                //  instead of this:
                //  if($this->areThereKids($id2) == "yes") {
                //  do this:
                    $this->dealWithKids($parent);
                }
             }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?