無限級分類是我們常用見的一個程序方法了,原理是得到有層級關系的數組,就是頂級是頂級分類,然后每個分類中有個children子數組,記錄它的子分類,這樣一級一級的分級數組.
算法的數據庫結構設計最為簡單,category表中一個字段id,一個字段fid(父id),這樣可以根據WHERE id = fid來判斷上一級內容,運用遞歸至最頂層.
我們先查出數組,代碼如下:
- <?php
- $a = array(
- 'AAAAAA' => array(
- 'aaaaaa' => array(
- '111111',
- '222222',
- '333333'
- ),
- 'bbbbbb' => array(
- '111111',
- '222222',
- '333333'
- ),
- 'cccccc' => array(
- '111111',
- '222222',
- '333333'
- ),
- ),
- 'BBBBBB' => array(
- 'aaaaaa' => array(
- '111111',
- '222222',
- '333333'
- ),
- 'bbbbbb'=> array(
- '111111',
- '222222',
- '333333'
- ),
- 'cccccc'=> array(
- '111111',
- '222222',
- '333333'
- ),
- ),
- 'CCCCCC' => array(
- 'aaaaaa'=> array(
- '111111',
- '222222',
- '333333'
- ),
- 'bbbbbb'=> array(
- '111111',
- '222222',
- '333333'
- ),
- 'cccccc' => array(
- '111111',
- '222222',
- '333333'
- ),
- ),
- );
- foreach ($a as $k=>$v){
- echo $k."<br>";
- // if(is_array($v)){
- foreach($v as $key=>$val){
- echo " ".$key."<br>";
- // }
- if(is_array($val)){
- foreach($val as $kkk=>$vall){
- echo " ".$vall."<br>";
- }
- }
- }
- echo "<br>";
- }
- /*******mysql查詢無限級分類的代碼******/
- /***
- $sql = "SELECT a.Title AS big, b.Title AS small
- FROM largeTitle AS a LEFT JOIN smallTitle AS b ON a.ID=b.LargeID";
- $a = array();
- $r = mysql_query($sql);
- while( $arr = mysql_fetch_array($r)){
- $a[$arr['big']] = $arr['small'];
- }
- ***/
- ?>
好了下面先讀取數據庫然后再遞歸讀出.
分類表,比如category,字段有 id,parentid,title,代碼如下:
- //查詢
- $dsql->SetQuery("SELECT * FROM category ORDER BY sortorder ASC");
- $dsql->Execute('parentlist');
- $array = array();
- $parentlist = array();
- while ($rs=$dsql->getObject('parentlist'))
- {
- if($rs->parentid == 0)
- {
- $parentlist[$rs->id] = (array)$rs;
- }
- else
- {
- $array[$rs->id] = (array)$rs;
- }
- }
- $parentlist = cat_options($parentlist, $array); //我們求的結果數組
- //$list父級分類的數組
- //$array是除父級分類外的全部分類的數組
- function cat_options(&$list,&$array)
- {
- foreach ($list as $key => $arr)
- {
- foreach ($array as $k => $value)
- {
- if($value['parentid'] == $arr['id'])
- {
- $list[$key]['children'][] = $value;
- unset($array[$k]);
- }
- }
- }
- foreach ($list as $key => $arr)
- {
- if(is_array($arr['children']) && count($arr['children']) > 0)
- {
- $list[$key]['children'] = cat_options($list[$key]['children'], $array);
- }
- }
- return $list;
- }
其它的方法,設置fid字段類型為varchar,將父類id都集中在這個字段里,用符號隔開,比如:1,3,6,這樣可以比較容易得到各上級分類的ID,而且在查詢分類下的信息的時候,可以使用:SELECT * FROM category WHERE pid LIKE “1,3%”,代碼如下:
- --
- -- 表的結構 `category`
- --
- CREATE TABLE IF NOT EXISTS `category` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `type` int(11) NOT NULL COMMENT '1為文章類型2為產品類型3為下載類型',
- `title` varchar(50) NOT NULL,
- `lft` int(11) NOT NULL,
- `rgt` int(11) NOT NULL,
- `lorder` int(11) NOT NULL COMMENT '排序',
- `create_time` int(11) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;
- --
- -- 導出表中的數據 `category`
- --
- INSERT INTO `category` (`id`, `type`, `title`, `lft`, `rgt`, `lorder`, `create_time`) VALUES
- (1, 1, '頂級欄目', 1, 18, 1, 1261964806),
- (2, 1, '公司簡介', 14, 17, 50, 1264586212),
- (3, 1, '新聞', 12, 13, 50, 1264586226),
- (4, 2, '公司產品', 10, 11, 50, 1264586249),
- (5, 1, '榮譽資質', 8, 9, 50, 1264586270),
- (6, 3, '資料下載', 6, 7, 50, 1264586295),
- (7, 1, '人才招聘', 4, 5, 50, 1264586314),
- (8, 1, '留言板', 2, 3, 50, 1264586884),
- (9, 1, '總裁', 15, 16, 50, 1267771951);
- /**
- * 顯示樹,把所有的節點都顯示出來。
- * 1、先得到根結點的左右值(默認根節點的title為“頂級目錄”)。
- * 2、查詢左右值在根節點的左右值范圍內的記錄,并且根據左值排序。
- * 3、如果本次記錄右值大于前次記錄的右值則為子分類,輸出時候加空格。
- * @return array
- **/
- function display_tree(){
- //獲得root左邊和右邊的值
- $arr_lr = $this->category->where("title = '頂級欄目'")->find();
- //print_r($arr_lr);
- if($arr_lr){
- $right = array();
- $arr_tree = $this->category->query("SELECT id, type, title, rgt FROM category WHERE lft >= ". $arr_lr['lft'] ." AND lft <=".$arr_lr['rgt']." ORDER BY lft");
- foreach($arr_tree as $v){
- if(count($right)){
- while ($right[count($right) -1] < $v['rgt']){
- array_pop($right);
- }
- }
- $title = $v['title'];
- if(count($right)){
- $title = '|-'.$title;
- }
- $arr_list[] = array('id' => $v['id'], 'type' => $type, 'title' => str_repeat(' ', count($right)).$title, 'name' =>$v['title']);
- $right[] = $v['rgt'];
- }
- return $arr_list;
- }
- }
好了 只要這樣所有的分類都可以一次性查詢出來了,而不用通過遞歸了.
新聞熱點
疑難解答