如何在选择列表中显示类别,子类别,子子类别 - php / mysql?

时间:2014-08-01 16:40:07

标签: php mysql sql

我想在选择列表(下拉列表)中显示类别,子类别和子子类别,就像WordPress在其管理面板中显示的方式一样。首先看看我的数据库表(tb_categories) -

Database Table

我想要HTML格式的以下输出 -

Output

这两个项目"无"和"未分类"在代码中是硬编码的。我想知道如何使用选择列表选项按层次顺序显示类别及其子类别。

我正在尝试使用以下sql查询,其中我使用自联接。这是 -

SELECT
    `cat`.`category_name` AS 'category name',
    `cat2`.`category_name` AS 'parent category'
FROM
    `tb_categories` AS `cat`
LEFT JOIN `tb_categories` AS `cat2` ON `cat`.`category_parent` = `cat2`.`category_id`
ORDER BY
    'parent category'

它给出的输出是 -

Array
(
    [0] => Array
        (
            [0] => My Parent Category
            [category name] => My Parent Category
            [1] => 
            [parent category] => 
        )

    [1] => Array
        (
            [0] => Parent Category 2
            [category name] => Parent Category 2
            [1] => 
            [parent category] => 
        )

    [2] => Array
        (
            [0] => Parent Category 3
            [category name] => Parent Category 3
            [1] => 
            [parent category] => 
        )

    [3] => Array
        (
            [0] => My Child Category
            [category name] => My Child Category
            [1] => My Parent Category
            [parent category] => My Parent Category
        )

    [4] => Array
        (
            [0] => Sports
            [category name] => Sports
            [1] => 
            [parent category] => 
        )

    [5] => Array
        (
            [0] => Cricket is best
            [category name] => Cricket is best
            [1] => Sports
            [parent category] => Sports
        )

    [6] => Array
        (
            [0] => AJAX
            [category name] => AJAX
            [1] => 
            [parent category] => 
        )

    [7] => Array
        (
            [0] => hockey is best
            [category name] => hockey is best
            [1] => Sports
            [parent category] => Sports
        )

)

我不知道甚至不确定如何在该选择列表中显示上述数据。我们怎么做?我们怎样才能使用连接呢?如果我们使用连接,那么我们是否需要一些数组来存储和排序结果?还有我们如何在循环中使用多个查询来做到这一点?哪种方法最好?

3 个答案:

答案 0 :(得分:6)

假设您的给定数组在$ array中,您可以使用它。但正如我告诉你的那样,你应该选择id来处理具有相同名称的类别,并将它们用作选择框中的选项值:

  $options = get_options($array);
  echo "<select>";
  foreach($options as $val) {
    echo "<option>".$val."</option>";
  }
  echo "</select>";

  function get_options($array, $parent="", $indent="") {
    $return = array();
    foreach($array as $key => $val) {
      if($val["parent category"] == $parent) {
        $return[] = $indent.$val["category name"];
        $return = array_merge($return, get_options($array, $val["category name"], $indent."&nbsp;&nbsp;&nbsp;"));
      }
    }
    return $return;
  }

假设您现在将数组中的ID设为&#34; category_id&#34;和&#34; parent_category_id&#34;你可以用它。 &#34; x&#34;在$ return中键之前只是为了避免php更改你的键,因为它们是数字的。

  $options = get_options($array);
  echo "<select>";
  foreach($options as $key => $val) {
    echo "<option value='".substr($key,1)."'>".$val."</option>";
  }
  echo "</select>";

  function get_options($array, $parent=0, $indent="") {
    $return = array();
    foreach($array as $key => $val) {
      if($val["parent_category_id"] == $parent) {
        $return["x".$val["category_id"]] = $indent.$val["category name"];
        $return = array_merge($return, get_options($array, $val["category_id"], $indent."&nbsp;&nbsp;&nbsp;"));
      }
    }
    return $return;
  }

答案 1 :(得分:3)

这是最简单的类别表结构

+-------------------------+
| categories              |
+-------------------------+
| category_id   (int)     | PK
| parent_id     (int)     | Index
| category_name (varchar) |
| ...                     |
+-------------------------+

以下函数将递归获取所有类别并构建层次结构。如您所见,您可以选择要预先选择的值,也可以仅获取更改父级值的层次结构的一部分。

function build_category_tree(&$output, $preselected, $parent=0, $indent=""){
  $r = mysql_query("
    SELECT category_id, category_name FROM categories WHERE parent_id = " . $parent . "
  ");

  while($c = mysql_fetch_array($r, MYSQL_ASSOC)){
    $selected = ($c["category_id"] == $preselected) ? "selected=\"selected\"" : "";
    $output .= "<option value=\"" . $c["category_id"] . "\" " . $selected . ">" . $indent . $c["category_name"] . "</option>";
    if($c["category_id"] != $parent){
      build_category_tree($output, $preselected, $c["category_id"], $indent . "&nbsp;&nbsp;");
    }
  }
}

用法:

<?php 
build_category_tree($categories, 0); 
// if you want to preselect a value and start from some subcategory
build_category_tree($categories, 5, 2); 
?>

<!-- HTML -->
<select><?php echo $categories ?></select>
<!-- if you want to add some extra options -->
<select>
  <option value="-1">Choose a category</option> 
  <?php echo $categories ?>
</select>

附注:虽然此功能看起来很优雅,但如果您有数千个类别,请不要使用它。另外,在最终版本中使用MySQLi或PDO_MySQL扩展名。

答案 2 :(得分:1)

Database View For Categories

$con = mysqli_connect("localhost","root","","categories"); 
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql = mysqli_query($con,"SELECT `cat`.`categoryName` AS 'category name', `cat2`.`categoryName` AS 'parent category' FROM `product_category` AS `cat` LEFT JOIN `product_category` AS `cat2` ON `cat`.`parentId` = `cat2`.`categoryId` where `cat2`.`categoryName` !='NULL' order by `cat2`.`categoryName`");

  while($res=mysqli_fetch_array($sql,MYSQLI_ASSOC)){
  $cat[] = $res['category name'];
  $parent[]= $res['parent category'];
}
$parents = "";
for($i=0;$i<count($cat);$i++){
 if($parents!=$parent[$i]){
if($i!=0){ echo "</ul>"; }
 echo $parent[$i]."<ul><li>".$cat[$i]."</li>" ;
}else{

 echo "<li>".$cat[$i]."</li>" ;
}
$parents = $parent[$i];
}
echo "</ul>";

Output

表格更多有关php,ajax,jquery,mysql,面试问题的教程。请看我的博客hackandphp.com