在无序列表中显示类别

Displaying categories in unordered list

我 运行 在无序列表中排序和显示来自数据库的类别的问题。

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

$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 查询快?

编辑: 我尝试加入 tables,通过这个查询我得到了正确的 table.

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

但是如何处理 table in php 以获得无序列表?这会更快吗?

尝试这样的事情:

$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 结构。

试试这个查询:

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 将是子类别的名称
  • 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
    }
}

解释:

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