尝试创建导航的递归函数

时间:2015-06-26 18:15:12

标签: php sql function

我有产品类别,我有一个内置的导航。但是,有些类别有子类别,有些类别有子类别,等等,可能与子亚子类别一样深。

我想要一个漂亮的整洁导航,显示如下结构:

main-category (parent)
-sub-category
-sub-category (parent)
--sub-sub-category
--sub-sub-category
--sub-sub-category(current category)
--sub-sub-category
-sub-category
-sub-category
main-category

基本上,您可以查看当前类别和父类别的所有其他子类别。 我用很多代码实现了这一点,但我确信它可以用递归函数完成。

我必须构建导航的信息是一个包含所有类别的数组,从主类别开始,然后从那儿到孩子。

这是我目前的代码:

$structure = array( [0] => 0 [1] => 72 [2] => 51); // example
$navigation = '<ul id="category_side_nav">';
$qry0 = mysqli_query($con,"SELECT `categories_id`,`categories_name`,`categories_url` FROM `categories` WHERE `parent_id`=".$structure[0]." AND `categories_status`=1 ORDER BY `sort_order`");
while($row0 = mysqli_fetch_assoc($qry0)) {
    $navigation .= '<li class="navigation0"><a class="';
    if((isset($structure[1]) && $row0['categories_id'] == $structure[1]) || $row0['categories_id']==$id) $navigation .= 'current_navigation';
    else $navigation .= 'other_navigation';
    $navigation .= '" href="'.$base.$row0['categories_url'].'/">'.ucwords($row0['categories_name']).'</a></li>';
    if((isset($structure[1]) && $row0['categories_id'] == $structure[1]) || $row0['categories_id'] == $id) {  
        $cat1 = preg_replace("/_c[0-9_]+/", "", $row0['categories_url']).'/';
        $qry1 = mysqli_query($con,"SELECT `categories_id`,`categories_name`,`categories_url` FROM `categories` WHERE `parent_id`=".$row0['categories_id']." AND `categories_status`=1 ORDER BY `sort_order`");
        while($row1 = mysqli_fetch_assoc($qry1)) {  
            $navigation .= '<li class="navigation1"><a class="';
            if((isset($structure[2]) && $row1['categories_id'] == $structure[2]) || $row1['categories_id']==$id) $navigation .= ' current_navigation';
            else $navigation .= 'other_navigation';
            $navigation .= '" href="'.$base.$cat1.$row1['categories_url'].'/">'.ucwords($row1['categories_name']).'</a></li>';
            if((isset($structure[2]) && $row1['categories_id'] == $structure[2]) || $row1['categories_id'] == $id) {
                $cat2 = $cat1.preg_replace("/_c[0-9_]+/", "", $row1['categories_url']).'/';
                $qry2 = mysqli_query($con,"SELECT `categories_id`,`categories_name`,`categories_url` FROM `categories` WHERE `parent_id`=".$row1['categories_id']." AND `categories_status`=1 ORDER BY `sort_order`");
                while($row2 = mysqli_fetch_assoc($qry2)) {
                    $navigation .= '<li class="navigation2"><a class="';
                    if((isset($structure[3]) && $row2['categories_id'] == $structure[3]) || $row2['categories_id']==$id) $navigation .= ' current_navigation';
                    else $navigation .= 'other_navigation';
                    $navigation .= '" href="'.$base.$cat2.$row2['categories_url'].'/">'.ucwords($row2['categories_name']).'</a></li>';
                    if((isset($structure[3]) && $row2['categories_id'] == $structure[3]) || $row2['categories_id'] == $id) {
                        $cat3 = $cat2.preg_replace("/_c[0-9_]+/", "", $row2['categories_url']).'/';
                        $qry3 = mysqli_query($con,"SELECT `categories_id`,`categories_name`,`categories_url` FROM `categories` WHERE `parent_id`=".$row2['categories_id']." AND `categories_status`=1 ORDER BY `sort_order`");  
                        while($row3 = mysqli_fetch_assoc($qry3)) {
                            $navigation .= '<li class="navigation3"><a class="';
                            if((isset($structure[4]) && $row3['categories_id'] == $structure[4]) || $row3['categories_id']==$id) $navigation .= ' current_navigation';  
                            else $navigation .= 'other_navigation';                         
                            $navigation .= '" href="'.$base.$cat3.$row3['categories_url'].'/">'.ucwords($row3['categories_name']).'</a></li>';
                            if((isset($structure[4]) && $row3['categories_id'] == $structure[4]) || $row3['categories_id'] == $id) {
                                $cat4 = $cat3.preg_replace("/_c[0-9_]+/", "", $row3['categories_url']).'/';
                                $qry4 = mysqli_query($con,"SELECT `categories_id`,`categories_name`,`categories_url` FROM `categories` WHERE `parent_id`=".$row3['categories_id']." AND `categories_status`=1 ORDER BY `sort_order`");  
                                while($row4 = mysqli_fetch_assoc($qry4)) {
                                    $navigation .= '<li class="navigation4"><a class="';
                                    if((isset($structure[5]) && $row4['categories_id'] == $structure[5]) || $row4['categories_id']==$id) $navigation .= ' current_navigation';  
                                    else $navigation .= 'other_navigation';
                                    $navigation .= '" href="'.$base.$cat4.$row4['categories_url'].'/">'.ucwords($row4['categories_name']).'</a></li>';                              
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
$navigation .= '</ul>';

数据库只有category_id和parent_id。

我无法创建递归函数,因为我需要知道数组中的下一个条目,所以我可以相应地设置导航样式,这让我真的卡住了。

任何人都可以帮助我将其转换为递归函数或至少一些函数,以使用更少的代码使其更整洁。

// UPDATE

好的,我尝试通过增加数组来尝试一种不同的方式,但它有点像马车,但可能是继续进行的方式,如果有人有任何想法更像这样

function nav() {
    $cat_level = structure($this->id);
    $this->cats = array_reverse($cat_level);

    $nav = '<ul id="category_side_nav">';

    $nav .= $this->structure(0,BASE);

    $navigation .= '</ul>';
    return $navigation; 

}

function structure($i,$url) {
    if($i==0) $nav = '';
    $qry = mysqli_query($this->con,"SELECT `categories_id`,`categories_name`,`categories_url` FROM `categories` WHERE `parent_id`=".$this->cats[$i]." AND `categories_status`=1 ORDER BY `sort_order`");
    while($row = mysqli_fetch_assoc($qry)) {
        $nav .= '<li class="navigation'.$i.'"><a class="';
        if((isset($structure[$i+1]) && $row['categories_id'] == $this->cats[$i+1]) || $row['categories_id']==$this->id) $nav .= 'current_navigation';
        else $nav .= 'other_navigation';
        $nav .= '" href="'.$url.$row['categories_url'].'/">'.ucwords($row['categories_name']).'</a></li>';  
        if((isset($this->cats[$i+1]) && $row['categories_id'] == $this->cats[$i+1]) || $row['categories_id'] == $this->id) {  
            $url .= preg_replace("/_c[0-9_]+/", "", $row['categories_url']).'/';
            $this->structure($i+1,$url);
        }
    }
    return $nav;
}

1 个答案:

答案 0 :(得分:0)

伪代码,您可以创建存储标签和父项ID的单个DB表:

function render(parent_id){
select * from menu_table where parent_id = parent_id // null is not compared with = in mysql, use is null
foreach menu item as item {
render item - echo ul li etc, create indent
render(item->id) //recursive call with current item ID
closing tags for this menu item
}
return
}

数据库表:

You need to design your DB table, here are the columns:
ID, Label, Parent_ID

Then your main menu item would look like this:
1, Main, null (or zero)
Then subitems for this main menu would have the parent_id of 1
2, Submenu1, 1
3, Submenu2, 1

And so on...