CMS中的分類每每是能夠無限劃分子目錄的,存儲數據的過程比較容易實現,可是取目錄層級的方式卻比較難搞。php
經常使用的目錄劃分模式有毗鄰目錄模式和預排序遍歷樹(左右值無限分類法)。這裏只討論前一種模式的目錄獲取。sql
正常狀況下,數據庫是這樣設計的(模擬一些數據):數據庫
id title parent 1 新聞 0 2 生活 0 3 旅遊 0 4 國內 1 5 國際 1 6 社會 4 7 美食 2 8 景點 3
這裏只是模擬一個簡單的結構。數組
下面取出數據後,放在數組裏。函數
$cat = array( array( 'id' => 1, 'title' => '新聞', 'parent' => 0 ), ... );
這裏再也不詳細的寫數組了 如下是處理函數:設計
/** * 主要的處理函數,規整目錄的層級 * * @param array * * @return array */ public function get_categories($cats){ //取全部分類 if (!$cats || empty($cats)) { return false; } //將分類按級別整理成一個數組 $first = array(); $level = array(array(0)); $i = 0; while (count($cats) > 0) { foreach ($cats as $k => $v) { if (in_array($v['parent'], $level[$i])) { $first[$i][$v['id']] = $v; $level[$i+1][] = $v['id']; unset($cats[$k]); } } $i++; } //將數組按分類整理歸屬 $first = array_reverse($first);//將數組順序翻轉 $sorted = array(); $children = array();//定義一個存儲子節點的數組 foreach ($first as $key => $val) { if (!empty($children)) { foreach ($children as $num => $row) { $val[$num]['children'] = $row; } $children = array(); } foreach ($val as $num => $row) { if ($row['parent'] > 0) { $children[$row['parent']][] = $row; } } $sorted = $val; } //數組降維度 名稱修飾 return arr_align($sorted); }
在調用arr_algin以前直接打印結果,能夠獲得一個這樣的數組:code
array( 1 => array( 'id' => string '1', 'title' => string '新聞', 'parent' => string '0', 'children' => array( 0 => array( 'id' => string '4', 'title' => string '國內', 'parent' => string '1', 'children' => array( 0 => array( ... ) ) ) ... ) ), 2 => array( 'id' => string '2', 'title' => string '生活', 'parent' => string '0', ), 3 => array( 'id' => string '3', 'title' => string '旅遊', 'parent' => string '0', ) )
經過下面的遞歸函數將數組轉換成一個簡單的二位數組,將欄目按照層級展現出來:排序
/** * 將多維數組維度降爲2,欄目名稱按維度標註 * * @param array,int * * @return array */ function arr_align($arr,$level=0){ $level++;//這個變量會幫你打印好頗有頗有層次的'-- ' static $data;//定義一個靜態變量用來存儲最終結果 foreach ($arr as $val) { $temp = $val; $temp['title'] = str_repeat('-- ',$level).$temp['title']; if (isset($val['children'])) { unset($temp['children']); $data[] = $temp; arr_align($val['children'],$level);//遞歸調用 } else{ $data[] = $temp; } } return $data; }
處理後的結果:遞歸
0 => array( 'id' => string '1', 'title' => string '-- 新聞', 'parent' => string '0', ), 1 => array( 'id' => string '4', 'title' => string '-- -- 國內', 'parent' => string '1', ), 2 => array( 'id' => string '6', 'title' => string '-- -- -- 社會', 'parent' => string '4', ), 3 => array( 'id' => string '5', 'title' => string '-- -- 國際', 'parent' => string '1', ), 4 => array( 'id' => string '2', 'title' => string '-- 生活', 'parent' => string '1', ), 5 => array( 'id' => string '7', 'title' => string '-- -- 美食', 'parent' => string '2', ), 6 => array( 'id' => string '3', 'title' => string '-- 旅遊', 'parent' => string '0', ), 5 => array( 'id' => string '8', 'title' => string '-- -- 景點', 'parent' => string '3', ) )