簡體   English   中英

sql + php顯示帶有無限子類別的類別

[英]sql + php show categories with infinit sub-categories

我有下表:

CREATE TABLE category(
    category_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(20) NOT NULL,
    parent INT DEFAULT NULL
);

如何從表中構建選擇SQL,以便在php中獲得類別和子類別的完整樹? 我還想檢查某個項目是否有子級,因為我想添加一個class屬性。

例:

  • 電子產品
    • Smarthphones
      • 蘋果手機
        • iPhone 5S
        • iPhone 6
        • iPhone 6s
      • 三星
    • 電視
  • 餐飲

並且子類別可以超過此示例。

我可以在php中使用此功能來顯示菜單:

function treeview($array, $id = 0)
{

  foreach ($array as $arr)
  {

     if($arr[parent]==$id) {

     echo $arr[category_id].' '.$arr[parent].' '.$arr[name].'<br />';
     treeview($array, $arr['category_id']);

     }
   }
}

您也可以使用遞歸方法:

function buildTree($parent = null) {
    $sql = "SELECT * FROM `category` WHERE `parent` " . (is_null($parent) ? 'IS NULL' : "= '" . mysql_real_escape_string($parent) . "'");
    $result = mysql_query($sql) or die(mysql_error());
    $data = array();
    while ($row = mysql_fetch_assoc($result)) {
        $row['children'] = buildTree($row['category_id']);
        $data[] = $row;
    }
    return $data
}
$categories = buildTree();

使用Andrey Telesh演示的常用結構,您可以執行以下操作:

<?php
function executeSQLThenFetchAllRowsAsAssoc($sql)
{
    global $pdo;
    $stmt=$pdo->prepare($sql);
    $stmt->execute();
    return $stmt->fetchAll();
}
function buildTree($parent = null)
{
    if(empty($parent)){
    $sql = "SELECT * FROM `category` WHERE `parent` is null";
    }else{
    $sql = "SELECT * FROM `category` WHERE `parent`=$parent";
    }
    $rows=executeSQLThenFetchAllRowsAsAssoc($sql);
    $data = array();
    foreach($rows as $row) {
        $cat=buildTree($row['category_id']);
        $data[] = array('children'=>$cat,'id'=>$row['category_id'],'parent'=>$row['parent'],'name'=>$row['name']);
    }
    return $data;
}

function displayIt($cats,$depth=0)
{
    if($depth==0){echo '<ul>';}
    foreach($cats as $cat)
    {
    $hasChildren=count($cat['children'])>0;
    $class=$hasChildren?' class="menu-item-has-children"':'';
    echo '<li'.$class.' data-children="'.count($cat['children']).'">'.$cat['name'];
    if($hasChildren){echo '<ul>';displayIt($cat['children'],$depth+1);echo '</ul>';}
    echo '</li>';
    }
    if($depth==0){echo '</ul>';}
}


$pdo=new PDO('mysql:host=localhost; dbname=my_database_name;', 'my_username', 'my_password');
$tree=buildTree();
displayIt($tree);

無需關閉?> 只需確保最后用您自己的設置替換my_database_namemy_usernamemy_password 是的,此代碼將自行運行。
輸出將是:

<ul><li class="menu-item-has-children" data-children="2">Electronics<ul><li class="menu-item-has-children" data-children="2">Smarthphones<ul><li class="menu-item-has-children" data-children="3">iPhone<ul><li data-children="0">iPhone 5s</li><li data-children="0">iPhone 6</li><li data-children="0">iPhone 6s</li></ul></li><li data-children="0">Samsung</li></ul></li><li data-children="0">TV</li></ul></li><li data-children="0">Food</li></ul>

我測試的數據是:

CREATE TABLE IF NOT EXISTS `category` (
  `category_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `parent` int(11) DEFAULT NULL,
  PRIMARY KEY (`category_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;


INSERT INTO `category` (`category_id`, `name`, `parent`) VALUES
(1, 'Electronics', NULL),
(2, 'Smarthphones', 1),
(3, 'iPhone', 2),
(4, 'Food', NULL),
(5, 'Samsung', 2),
(6, 'iPhone 5s', 3),
(7, 'iPhone 6', 3),
(8, 'iPhone 6s', 3),
(9, 'TV', 1);

出於速度方面的考慮,建議您在使用buildTree()確定樹層次結構之后,將類別作為序列化的php對象進行緩存。 您可能還對僅直接緩存所需的HTML輸出或同時緩存兩者感興趣。 每當類別表更新時,只需更新緩存。 通過緩存,我的意思是有一個單獨的PHP文件,您將該文件包含在項目中,這樣您就可以在不干擾數據庫的情況下獲得可用的數據。

我在這種方法中使用引用(“&”):

function _getTree($tree_details){

$refs = array();
$list = array();

foreach ($tree_details as $data) {
$thisref = &$refs[ $data['branch_id'] ];

$thisref['branch_name'] = $data['branch_name'];
$thisref['parent_id'] = $data['parent_id'];
$thisref['branch_id'] = $data['branch_id'];

if ( empty($data['parent_id']) ){
$list[ $data['branch_id'] ] = &$thisref;
} else {
$refs[ $data['parent_id'] ]['children'][ $data['branch_id'] ] = &$thisref;
}

}

//check reviews tree
if( !empty($list) && count($list) ){
return $list;
}
return false;

} // getTree

此方法將返回所有類別的關聯數組,然后必須使用另一種使用遞歸函數繪制html的方法:

function drawBranchesSelectBox($branches_tree=NULL, $branch_id = 0, $options_string = '', $separator = '') {

if(empty($branches_tree)){
return false;
}

//loop through children
foreach ($branches_tree as $branches) {

$is_selected = ( $branch_id == $branches["branch_id"] ? ' selected="selected" ' : '' );
$options_string .= '' . $separator . $branches["branch_name"] . '' . "\n";

//check for subbranches
if (@is_array($branches['children']) && @count($branches['children'])) {
//call same method to get children
$options_string = drawBranchesSelectBox($branches['children'], $branch_id, $options_string, $separator . '    ');
}

} //foreach

return $options_string;

} //drawBranchesSelectBox

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM