php中的菜单层次关系

时间:2016-05-03 18:24:50

标签: php mysql

我们在像这样的表中有层次关系

表名:类别

 id       parent_id    title
  1         0           main menu
  2         1           sub_menu1
  3         2           sub_sub_menu1

另一个表:域

id        cat_id        name
 1           1           main domain
 2           2           sub domain
 3           3           sub sub domain

我们正在尝试显示类别和子类别 正如我的朋友建议过于复杂和太昂贵,无法通过sql显示这种类型的关系,所以我们通过php显示这一点。

我们写了这段代码: -

function getSubCatCount($data,$parent){
    $count=0;
    $count =$count+ domainCatCount($parent);
    return $count;
}


function menuList($data, $parent = 0,$st )
{
    static $i = 0;
    $tab = str_repeat(" ",$i);
    if($data[$parent])
    {
    $html .= "";
    $i++;


    if($i==1)
                $html .= '<ul data-menu="main" class="menu__level">';
    else{
                $html .= '<ul data-menu="submenu-'.$parent.'" class="menu__level">';
    }
    $tmpLis="";
        foreach($data[$parent] as $v)
        {
            $html .= '<li class="menu__item"><a href="#" class="menu__link ';
            $child = menuList($data, $v['id'],"false");
            $html .= '" data-submenu="submenu-'.$v['id'].'" ';      
            //if(!$child)
            {
                $tmpLis.=domainHtmlList($v['id']);
            }
            $html .= '>';


            $html .= $v['title'].'<div style="float: right;"><table style="width: 145px;"><tr><td style="width: 30%;"><img src="https://cdn3.iconfinder.com/data/icons/metro-explorer/512/my_location-512.png"  style="width: 20px;height: 20px;" title="usages">'.getUsages($v['id']).'</td><td style="width: 30%;"><img src="http://www.clubs.uci.edu/cae/a/src/1432405005258.png"  style="width: 20px;height: 20px;" title="domains">'.getDomainCount($data,$v['id']).'</td><td style="width: 30%;"><img src="https://cdn2.iconfinder.com/data/icons/flat-ui-icons-24-px/24/eye-24-128.png"  style="width: 20px;height: 20px;" title="views">'.getViews($v['id']).'</td></tr></table></div></a></li>';
//if (preg_match_all('/<[a-z \'"]*data-menu=[\'"]submenu-'.$v['id'].'[\'"][^>]*>([^<]*)/i', $html, $matches)) {
    //print_r($matches);
    //$child = menuList($data, $v['id'],"true");
//$html .= $child;
//} 

        }
            if($st!="true")
            $html .= "</ul>";
            $html .=$tmpLis;
        foreach($data[$parent] as $v)
        {
            $child = menuList($data, $v['id'],"false");
            if($child)
            {
                $i–;
                $html .= $child;
            }
        }
        return $html;
    }
    else
    {
        return false;
    }
}



function domainHtmlList($i){
global $db; 

$domainCatRows = $db->getRows("SELECT * FROM  `url_domain` WHERE  `category` ='".$i."'");
if(count($domainCatRows)>0)
    $html = '<ul data-menu="submenu-'.$i.'" class="menu__level">';
foreach($domainCatRows as $ff) 
{
$dom=$ff['domain'];
$count=0;
if($ff['domain']=="[[[main_url]]]")
$dom="123.yt";
$html .= '<li class="menu__item"><a href="#" class="menu__link ';
    $html .=  'submenu-child" data-key="'.$ff['id'].'" data-domain="'.$dom.'" ';
$html .= '>';
$domainId=$ff['id'];
    //for usages
    $shortUrlRows = $db->getRows("SELECT count(*) as usages_count FROM `shorturl` WHERE `urlDomainId` in (".$domainId.") ");
    foreach($shortUrlRows as $val) 
    {
        $count=$count+$val['usages_count']; 
    }   
    //for views
    //$tmp= $db->getRows("SELECT count(*) as count FROM  `stats` WHERE  `url` like '%".$dom."%'");  
    //echo "SELECT * FROM  `stats` WHERE  `reffer` like '%".$dom."%'"."<br/>";
    //print_r($tmp);

    $tmp= $db->getRows("SELECT GROUP_CONCAT(id SEPARATOR ',') as shortUrlDomain FROM  `shorturl` WHERE  `urlDomainId` in (".$domainId.")");
    //echo "SELECT GROUP_CONCAT(id SEPARATOR ',') as shortUrlDomain FROM  `shorturl` WHERE  `urlDomainId` in (".$domainId.")"."<br/>";
    $tmpsts= $db->getRows("SELECT count(*) as count FROM  `stats` WHERE  `page_title` in (".$tmp[0]['shortUrlDomain'].")");
    //echo "SELECT count(*) as count FROM  `stats` WHERE  `page_title` in (".$tmp[0]['shortUrlDomain'].")"."<br/>";
    //$count=$count+$tmpsts[0]['count'];        

     $html .="<div style='float:right;'><table style='width: 140px;'><tr><td style='width: 30%;'><img src='https://cdn3.iconfinder.com/data/icons/metro-explorer/512/my_location-512.png'  style='width: 20px;height: 20px;' title='usages'>".$count."</td><td style='width: 30%;'><img src='https://cdn2.iconfinder.com/data/icons/flat-ui-icons-24-px/24/eye-24-128.png'  style='width: 20px;height: 20px;' title='views'>".$tmpsts[0]['count']."</td></tr></table></div>";
   $html .= $dom.'</a>';
            $html .='</li>';
    }
if(count($domainCatRows)>0)
$html .= "</ul>";
return $html;
} 

现在问题是当我们将子类别和域都放在一个类别中时它不显示两者。它只显示子类别或域。我们尝试了所有的东西但没有工作。那么我们如何展示这种关系?

1 个答案:

答案 0 :(得分:0)

我建议有问题的每个人使用嵌套树模型&#39;。

在您的类别表中创建2个新的int列(lft和rgt),并用算法提供的值填充它们(只是阅读一些文档,它不是很难理解)。 完成此操作后,您可以使用此查询获取所有主要类别:

SELECT * FROM categories WHERE parent_id = 0 OR parent_id IS NULL

现在,对于每个主要类别,让她所有的孩子。

SELECT * FROM categories 
WHERE lft >= (
      SELECT lft FROM categories
      WHERE id = {$id}
) AND rgt <= (
      SELECT rat FROM categories
      WHERE id = {$id}
)
ORDER BY lft;

维基百科帮助我很多算法: https://en.wikipedia.org/wiki/Nested_set_model

另外,还有一些像这样的php库。 http://www.sideralis.org/baobab/

我希望它会对你有帮助,

问候。