無限級分類是所有程序開發中會碰到的一個問題,下面我來介紹php+mysql實現的一個無限級分類程序,有需要的朋友可參考參考。
下面給大家看看我的數據庫結構吧:數據庫的名字為:fa_category
Field
Type
Comment
cid
int(11)
分類id
catename
varchar(255)
分類名字
catetype
int(1)
分類類型,1為單頁面,2為普通分類
catdir
varchar(255)
英文目錄
display
int(1)
1為顯示,2為不顯示
keywords
varchar(255)
欄目關鍵字
description
text
欄目描述
ctime
int(11)
創建時間
parentid
int(11)
父節點id,最高節點父節點為0
我們使用一個parentid字段來記錄父節點的id,如果parentid為0,則為root。不多說,我們看看代碼怎麼寫吧。我們要實現的功能就是如圖片所示:
怎麼樣把它這樣顯示呢?這個問題我想了很久,先看看這段SQL語句吧,
代碼如下
復制代碼
SELECT c.cat_id, c.cat_name, c.measure_unit, c.parent_id, c.is_show, c.show_in_nav, c.grade ,c.sort_order, COUNT( s.cat_id ) AS has_children
FROM ecs_category AS c
LEFT JOIN ecs_category AS s ON s.parent_id = c.cat_id
GROUP BY c.cat_id
ORDER BY c.parent_id, c.sort_order ASC
用左連接連接一個表,返回一個字段 has_children,這個字段是記錄有多少子節點。
看看代碼吧,
代碼如下
復制代碼
public function getCategory($catid=0,$re_type = true,$selected=0)
{
$db = new Public_DataBase();
$sql = 'select c.cid,c.catename,c.catetype,c.ctime,c.parentid,count(s.cid) as has_children from '.
__MYSQL_PRE.'category as c left join '.
__MYSQL_PRE.'category as s on s.parentid=c.cid group by c.cid order by c.parentid asc';
$res = $db->selectTable($sql);
$cateInfo = self::getChildTree($catid,$res);
if($re_type==true)
{
$select = '';
foreach($cateInfo as $val)
{
$select .= '<option value="' . $val['cid'] . '" ';
$select .= ($selected == $val['cid']) ? "selected='ture'" : '';
$select .= '>';
if($val['level']>0)
{
$select .= str_repeat(' ', $val['level'] * 4);
}
$select .= htmlspecialchars(addslashes($val['catename']), ENT_QUOTES) . '</option>';
}
return $select;
}
else
{
foreach($cateInfo as $key=>$val)
{
if($val['level']>0)
{
$cateInfo[$key]['catename'] = "|".str_repeat(' ', $val['level'] * 8)."└─".$val['catename'];
}
}
return $cateInfo;
}
}
/**
* 通過父ID遞歸得到所有子節點樹
* @param int $catid 上級分類
* @param array $arr 含有所有分類的數組
* @return array
*/
public function getChildTree($catid,$arr)
{
$level = $last_cat_id = 0;
while (!empty($arr))
{
foreach($arr as $key=>$value)
{
$cid = $value['cid'];
if ($level == 0 && $last_cat_id == 0)
{
if ($value['parentid'] > 0)
{
break;
}
$options[$cid] = $value;
$options[$cid]['level'] = $level;
$options[$cid]['id'] = $cid;
$options[$cid]['name'] = $value['catename'];
unset($arr[$key]);
if ($value['has_children'] == 0)
{
continue;
}
$last_cat_id = $cid;
$cat_id_array = array($cid);
$level_array[$last_cat_id] = ++$level;
continue;
}
if ($value['parentid'] == $last_cat_id)
{
$options[$cid] = $value;
$options[$cid]['level'] = $level;
$options[$cid]['id'] = $cid;
$options[$cid]['name'] = $value['catename'];
unset($arr[$key]);
if ($value['has_children'] > 0)
{
if (end($cat_id_array) != $last_cat_id)
{
$cat_id_array[] = $last_cat_id;
}
$last_cat_id = $cid;
$cat_id_array[] = $cid;
$level_array[$last_cat_id] = ++$level;
}
}
elseif ($value['parentid'] > $last_cat_id)
{
break;
}
}
$count = count($cat_id_array);
if ($count > 1)
{
$last_cat_id = array_pop($cat_id_array);
}
elseif ($count == 1)
{
if ($last_cat_id != end($cat_id_array))
{
$last_cat_id = end($cat_id_array);
}
else
{
$level = 0;
$last_cat_id = 0;
$cat_id_array = array();
continue;
}
}
if ($last_cat_id && isset($level_array[$last_cat_id]))
{
$level = $level_array[$last_cat_id];
}
else
{
$level = 0;
}
}
return $options;
}用smarty的一個循環就可以把它顯示出來 效果和上面圖片的一樣!大家有什麼問題可以給我留言。