在无序列表中显示类别

时间:2016-03-10 11:55:13

标签: php mysql performance nested-lists

我遇到了一个问题,在无序列表中排序和显示数据库中的类别。

我写了这段代码来完成任务:

$roots = $GLOBALS['sql']->query("SELECT `id`,`name` FROM `category` WHERE `parent`='0'");
$out = '<ul>';
foreach($roots as $root){
    $out .= '<li>'.$root['name'].'<ul>';
    $downs = $GLOBALS['sql']->query("SELECT `id`,`name` FROM `category` WHERE `parent`='".$root['id']."'");
    foreach($downs as $down){
        $out .= '<li>'.$down['name'].'<ul>';
        $bots = $GLOBALS['sql']->query("SELECT `name` FROM `category` WHERE `parent`='".$down['id']."'");
        foreach($bots as $bot){
            $out .= '<li>'.$bot['name'].'</li>';
        }
        $out .= '</ul></li>';
    }
    $out .= '</ul></li>';
}
$out .= '</ul>';
return str_replace('<ul></ul>', '', $out);

如果有很多类别,这似乎有很长的运行时间。有更有效的方法吗? 或者一般来说,php数组处理比MySQL查询更快?

编辑: 我尝试加入表格,通过这个查询,我得到了正确的表格。

SELECT 
       root.name  AS root_name, 
       down1.name AS down1_name, 
       down2.name AS down2_name 
FROM
            category AS root
  LEFT JOIN category AS down1 ON down1.parent = root.id 
  LEFT JOIN category AS down2 ON down2.parent = down1.id
WHERE 
      root.parent = '0' 
ORDER BY 
      root_name, down1_name, down2_name

但是如何在php中处理这个表以获得无序列表呢?这更快吗?

2 个答案:

答案 0 :(得分:0)

尝试这样的事情:

$rows = $GLOBALS['sql']->query("
    SELECT
        root.name AS root_name,
        down1.name AS down1_name,
        down2.name AS down2_name
    FROM category AS root
    LEFT JOIN category AS down1 ON down1.parent = root.id
    LEFT JOIN category AS down2 ON down2.parent = down1.id
    WHERE root.parent = '0'
    ORDER BY root_name, down1_name, down2_name
");

$tree = array();
foreach ($rows as $row) {
    $tree[$row['root_name']][$row['down1_name'] = $row['down2_name'];
}

$out = '';
foreach ($tree as $rootName => $root) {
    $out .= "<li>{$rootName}<ul>";  
    foreach ($root as $down1Name => $down1) {
        $out .= "<li>{$down1Name}<ul>";
        foreach ($down1 as $down2Name) {
            $out .= "<li>{$down2Name}</li>";
        }   
        $out .= "</ul></li>";
    }
    $out .= "</ul></li>";
}

在第一个循环(foreach ($rows as $row))中,您构建了一个树形结构的数组。在第二个嵌套循环中,您将构建HTML结构。

答案 1 :(得分:0)

尝试此查询:

select main_cat.name as main_category, sub_cat.name as sub_category, group_join(',', bot_cat.name) as bot_categories
from category main_cat
join category sub_cat
on (main_cat.parent = 0) and (sub_cat.parent = main.cat.id)
join category bot_cat
on bot_cat.parent = sub_cat.id
group by main_cat.name, sub_cat.name
order by main_cat.name, sub_cat.name

这将产生三列结果集:

  • main_category将是主要类别的名称
  • sub_category将是subactegory的名称
  • bot_categories将是机器人类别的逗号分隔值集

查询按类别名称和子类别名称分组,并按这些值排序。

PHP用法:

$previousCategory = null;
$categories = $GLOBALS['sql']->query("
    select main_cat.name as main_category, sub_cat.name as sub_category, group_join(',', bot_cat.name) as bot_categories
    from category main_cat
    join category sub_cat
    on (main_cat.parent = 0) and (sub_cat.parent = main.cat.id)
    join category bot_cat
    on bot_cat.parent = sub_cat.id
    group by main_cat.name, sub_cat.name
    order by main_cat.name, sub_cat.name
");

foreach ($categories as $category) {
    $newCat = ($category["main_category"] !== $previousCategory);
    $previousCategory = $category["main_category"];
    if ($newCat) {
        //Handle new cat start
    }
    //Handle subcategory start ($category["sub_category"])
    $bots = explode(',', $category['bot_categories']);
    foreach ($bots as $bot) {
        //Handle bot category
    }
    //Handle subcategory end ($category["sub_category"])
    if ($newCat) {
        //Handle new cat end
    }
}

说明:

您的程序很慢,因为它必须发送根类别的查询,每个根类别的查询以获取其子类别以及查询每个子类别以获取其机器人类别。这导致了许多发送到数据库的请求。相反,您可以通过单个查询解决问题。