3

我有一个 MySQL 表“产品”,其中有一个名为“类别”的列。在此字段中,您可以找到每个产品的类别层次结构作为字符串。例如:

female / dresses / long
female / dresses / short
female / shoes  
male / shoes / sneakers / skate
...

我选择了所有不同的类别:

$result = $mysqli->query("SELECT DISTINCT category FROM products ORDER BY category");

现在,我希望能够将这些类别打印为嵌套的 HTML 列表,例如

  • 女性
    • 连衣裙
      • 短的
  • 男性
      • 运动鞋
        • 滑冰

任何建议将不胜感激。谢谢!

编辑:我从几个 csv 文件中获取数据,所以不需要转换类别的解决方案会很棒!

4

2 回答 2

1

只需使用类别作为节点的键来构建您的树。例如 :

$categoryLines = array(
    "female / dresses / long",
    "female / dresses / short",
    "female / shoes",
    "male / shoes / sneakers / skate"
);

function buildCategoryTree($categoryLines, $separator) {
    $catTree = array();
    foreach ($categoryLines as $catLine) {
       $path = explode($separator, $catLine);
       $node = & $catTree;
       foreach ($path as $cat) {
           $cat = trim($cat);
           if (!isset($node[$cat])) {
               $node[$cat] = array();
           }
           $node = & $node[$cat];
       }
    }
    return $catTree;
}

function displayCategoryTree($categoryTree, $indent = '') {
    foreach ($categoryTree as $node => $children) {
        echo $indent . $node . "\n";
        displayCategoryTree($children, $indent . '|- ');
    }
}

$categoryTree = buildCategoryTree($categoryLines, '/');

现在,var_export($categoryTree)将输出:

array (
  'female' => array (
    'dresses' => array (
      'long' => array (),
      'short' => array (),
    ),
    'shoes' => array (),
  ),
  'male' => array (
    'shoes' => array (
      'sneakers' => array (
        'skate' => array (),
      ),
    ),
  ),
)

并将displayCategoryTree($categoryTree)输出:

female
|- dresses
|- |- long
|- |- short
|- shoes
male
|- shoes
|- |- sneakers
|- |- |- skate

** 编辑 **

获取树的 HTML 表示:

function displayHtmlCategoryTree($categoryTree, $id = null, $pathSeparator = '/', $parents = '') {
    if (empty($categoryTree)) return '';

    $str = '<ul' . (!empty($id) ? ' id="'.$id.'"' : '') . '>';
    foreach ($categoryTree as $node => $children) {
        $currentPath = $parents . (empty($parents) ? '' : $pathSeparator) . $node;
        $str .= '<li title="' . $currentPath . '">' . $node . 
                displayHtmlCategoryTree($children, null, $pathSeparator, $currentPath) . 
                '</li>';
    }
    $str .= '</ul>';
    return $str;
}

echo displayHtmlCategoryTree($categoryTree, "test", ' / ');

并将输出:

<ul id="test"><li title="female">female<ul><li title="female / dresses">dresses<ul><li title="female / dresses / long">long</li><li title="female / dresses / short">short</li></ul></li><li title="female / shoes">shoes</li></ul></li><li title="male">male<ul><li title="male / shoes">shoes<ul><li title="male / shoes / sneakers">sneakers<ul><li title="male / shoes / sneakers / skate">skate</li></ul></li></ul></li></ul></li></ul>
于 2013-09-10T13:04:21.490 回答
0

正如其他人在评论中提到的那样,你最好使用nested tree sets这种分类,但是既然你问过你不想改变你的分类系统和如果你不关心你的运行时的方案,只有当你不关心你的运行时重载,你可以使用我写的这段代码。

用于填充类别数组:

<?php
  $rows = array(
    "female/dresses/long",
    "female/dresses/short",
    "female/dresses/short/1",
    "female/dresses/short/2",
    "female/dresses/short/2/1",
    "female/shoes",
    "male/shoes/sneakers/skate"
  );

  $categories = array();

  function populate()
  {
    global $rows;
    global $categories;

    foreach($rows as $row)
    {
      $category_array = explode(" / ", $row);

      $categories = place($categories, $category_array);
    }
  }

  function place($categories, $category, $counter = 0)
  {
    if($counter < count($category))
    {
      if(!isset($categories[$category[$counter]]))
      {
        $categories[$category[$counter]] = array();
      }
      else if($counter == count($category) - 1)
      {
        $categories[$category[$counter]][] = $category[$counter];
      }

      // Recurse
      $categories[$category[$counter]] = place($categories[$category[$counter]], $category, $counter + 1);
    }

    return $categories;
  }

  // Populate categories
  populate();
?>

您可以将 my foreachon替换$rows为您的 fetchwhile循环。

用于显示类别:

<?php
  function display($items)
  {
    foreach($items as $k => $v)
    {
      echo "<li>" . $k;

      if(is_array($v))
      {
        echo "<ul>";

        display($v);

        echo "</ul>";
      }

      echo "</li>";
    }
  }
?>

<!DOCTYPE HTML>

<html>

<head>
  <title>Categories</title>
</head>

<body>
  <ul>
  <?php
    // Display categories
    display($categories);
  ?>
  </ul>
</body>

</html>

当前演示:

female
    dresses
        long
        short
            1
            2
                1
    shoes

male
    shoes
        sneakers
            skate
于 2013-09-10T12:49:02.427 回答