本文章總結了兩款PHP無限級分類實現程式碼,有需要學習的朋友可參考一下。
主要思路:首先看第三行和第四行,父類ID(PARENTID)的值是1,表示屬於id=1這個類的子類,而,一,二兩行因為是一級分類,沒有上級分類,所以父類ID(PARENTID)的值是0,表示初級分類,依次類推便實現了無限級分類。最終的效果是:
├一級分類A
├─┴二級分類A
├─┴二級分類B
├一級分類B
然後就是程式,這裡以PHP作為描述語言,可以很方便的改成其他語言,因為原理相似,就是一個遞迴而已。
<?php$dbhost = "localhost"; // 資料庫主機名稱$dbuser = "root"; // 資料庫使用者名稱$dbpd = "123456"; // 資料庫密碼$dbname = "test"; // 資料庫名mysql_connect($dbhost,$dbuser,$dbpd); //串連主機mysql_select_db($dbname); //選擇資料庫mysql_query("SET NAMES 'utf8'");display_tree("├",0);function display_tree($tag,$classid) { $result = mysql_query(" SELECT * FROM ylmf_class WHERE parentid = '" . $classid . "' ;" ); while ($row = mysql_fetch_array($result)) { // 縮排顯示節點名稱 echo $tag.$row['classname'] . "<br/>"; //再次調用這個函數顯示子節點的子節點 display_tree($tag."─┴",$row['id']); }}?>
在表格中顯示
TreeTable通過對儲存格的行合并和列合并實現了無限層級也能較好的展示層級架構。
1.構建ID/PID/NAME的數組,後期可通過資料庫產生的動態資料。Tree演算法請點擊
array(* 1 => array('id'=>'1','parentid'=>0,'name'=>'一級欄目一'),* 2 => array('id'=>'2','parentid'=>0,'name'=>'一級欄目二'),* 3 => array('id'=>'3','parentid'=>1,'name'=>'二級欄目一'),* 4 => array('id'=>'4','parentid'=>1,'name'=>'二級欄目二'),* 5 => array('id'=>'5','parentid'=>2,'name'=>'二級欄目三'),* 6 => array('id'=>'6','parentid'=>3,'name'=>'三級欄目一'),* 7 => array('id'=>'7','parentid'=>3,'name'=>'三級欄目二')* )
2. 匯入TreeTable類庫。
代碼如下:
import('@.ORG.Util.TableTree'); //Thinkphp匯入方法
3. 產生TreeTable HTML代碼
$treeTable->init($treearr);echo $treeTable->get_treetable();
注意:get_treetable()只生產表體部門,<TALBE></TABLE>請自行構建。
完整代碼
<?php/*** File name: TreeTable.class.php* Description: 通用的表格無限級分類* *//*** 表格展示無限分類是將無線分類已表格的形式表現出來,更好的能體現出分類的所屬關係* 使用方法:* 1. 執行個體化分類* $treeTable = new TreeTable();* 2. 初始化分類,$treearr必須是一個多維陣列且包含 id,parentid,name欄位* $treeTable->init($treearr);* 3. 擷取無限分類HTML代碼* echo $treeTable->get_treetable();* */class TreeTable {/*** 產生樹型結構所需要的2維數組* @var array*/public $arr = array();/*** 表格列數* @var int*/public $columns = 0;/*** 表格行數* @var int*/public $rows = 0;/*** 初始化TreeTable資料* @param array 2維數組* array(* 1 => array('id'=>'1','parentid'=>0,'name'=>'一級欄目一'),* 2 => array('id'=>'2','parentid'=>0,'name'=>'一級欄目二'),* 3 => array('id'=>'3','parentid'=>1,'name'=>'二級欄目一'),* 4 => array('id'=>'4','parentid'=>1,'name'=>'二級欄目二'),* 5 => array('id'=>'5','parentid'=>2,'name'=>'二級欄目三'),* 6 => array('id'=>'6','parentid'=>3,'name'=>'三級欄目一'),* 7 => array('id'=>'7','parentid'=>3,'name'=>'三級欄目二')* )*/public function init($arr=array()){if(!is_array($arr)) return false;foreach ($arr as $k=>$v) {$this->arr[$v['id']] = $v;}foreach ($this->arr as $k => $v){$this->arr[$k]['column'] = $this->get_level($v['id']); // Y軸位置$this->arr[$k]['arrchildid'] = $this->get_arrchildid($v['id']); // 所有子節點$this->arr[$k]['arrparentid'] = $this->get_arrparentid($v['id']); // 所有父節點$this->arr[$k]['child_bottom_num'] = $this->get_child_count($v['id']); // 所有底層元素節點}$this->columns = $this->get_columns(); // 總行數$this->rows = $this->get_rows(); // 總列數// 按照arrparentid和id號進行排序$this->sort_arr();foreach ($this->arr as $k => $v){$this->arr[$k]['row'] = $this->get_row_location($v['id']); // X軸位置$this->arr[$k]['rowspan'] = $v['child_bottom_num']; // 行合并數$this->arr[$k]['colspan'] = $v['child_bottom_num'] == 0 ? $this->columns - $v['column'] + 1 : 0; //列合并數}return $this->get_tree_arr();}/*** 擷取數組* */public function get_tree_arr(){return is_array($this->arr) ? $this->arr : false;}/*** 按arrparentid/id號依次重新排序數組* */public function sort_arr(){// 要進行排序的欄位foreach ($this->arr as $k => $v){$order_pid_arr[$k] = $v['arrparentid'];$order_iscost[] = $v['sort'];$order_id_arr[$k] = $v['id'];}// 先根據arrparentid排序,再根據排序,id號排序array_multisort($order_pid_arr, SORT_ASC, SORT_STRING,$order_iscost, SORT_DESC, SORT_NUMERIC,$order_id_arr, SORT_ASC, SORT_NUMERIC,$this->arr);// 擷取每一個節點層次for ($column = 1; $column <= $this->columns; $column++) {$row_level = 0;foreach ($this->arr as $key => $node){if ($node['column'] == $column){$row_level++;$this->arr[$key]['column_level'] = $row_level;}}}// 重新計算以ID作為鍵名foreach ($this->arr as $k=>$v) {$arr[$v['id']] = $v;}$this->arr = $arr;}/*** 得到父級數組* @param int* @return array*/public function get_parent($myid){$newarr = array();if(!isset($this->arr[$myid])) return false;$pid = $this->arr[$myid]['parentid'];$pid = $this->arr[$pid]['parentid'];if(is_array($this->arr)){foreach($this->arr as $id => $a){if($a['parentid'] == $pid) $newarr[$id] = $a;}}return $newarr;}/*** 得到子級數組* @param int* @return array*/public function get_child($myid){$a = $newarr = array();if(is_array($this->arr)){foreach($this->arr as $id => $a){if($a['parentid'] == $myid) $newarr[$id] = $a;}}return $newarr ? $newarr : false;}/*** 擷取當前節點所在的層級* @param $myid 當前節點ID號* */public function get_level($myid, $init = true){static $level = 1;if($init) $level = 1;if ($this->arr[$myid]['parentid']) {$level++;$this->get_level($this->arr[$myid]['parentid'], false);}return $level;}/*** 擷取當前節點所有底層節點(沒有子節點的節點)的數量* @param $myid 節點ID號* @param $init 第一次載入將情況static變數* */public function get_child_count($myid, $init = true){static $count = 0;if($init) $count = 0;if(!$this->get_child($myid) && $init) return 0;if($childarr = $this->get_child($myid)){foreach ($childarr as $v){$this->get_child_count($v['id'], false);}}else{$count++;}return $count;}/*** 擷取節點所有子節點ID號* @param $catid 節點ID號* @param $init 第一次載入將情況static初始化* */public function get_arrchildid($myid, $init = true) {static $childid;if($init) $childid = '';if(!is_array($this->arr)) return false;foreach($this->arr as $id => $a){if($a['parentid'] == $myid) {$childid = $childid ? $childid.','.$a['id'] : $a['id'];$this->get_arrchildid($a['id'], false);}}return $childid ;}/*** 擷取該節點所有父節點ID號* @param $id 節點ID號* */public function get_arrparentid($id, $arrparentid = '') {if(!is_array($this->arr)) return false;$parentid = $this->arr[$id]['parentid'];if($parentid > 0) $arrparentid = $arrparentid ? $parentid.','.$arrparentid : $parentid;if($parentid) $arrparentid = $this->get_arrparentid($parentid, $arrparentid);return $arrparentid;}/*** 擷取節點所在地行定位* @param $myid 節點ID號*/public function get_row_location($myid){$nodearr = $this->arr;// 擷取每一個節點所在行的位置foreach ($nodearr as $key => $node){if($myid == $node['id']) {$node_row_count = 0;$arrparentid = explode(',', $node['arrparentid']);// 所有父節點小於當前節點層次的底層節點等於0的元素foreach ($arrparentid as $pid){foreach ($nodearr as $node_row){if($node_row['column'] == $nodearr[$pid]['column'] && $nodearr[$pid]['column_level'] > $node_row['column_level'] && $node_row['child_bottom_num'] == 0){$node_row_count ++;}}}// 所有當前節點並且節點層次(rowid_level)小於當前節點層次的個數foreach ($nodearr as $node_row){if($node['column'] == $node_row['column'] && $node_row['column_level'] < $node['column_level']){$node_row_count += $node_row['child_bottom_num'] ? $node_row['child_bottom_num'] : 1;}}$node_row_count++;break;}}return $node_row_count;}/*** 擷取表格的行數* */public function get_rows(){$row = 0;foreach ($this->arr as $key => $node){if($node['child_bottom_num'] == 0){$rows++; // 總行數}}return $rows;}/*** 擷取表格的列數* */public function get_columns(){$columns = 0 ;foreach ($this->arr as $key => $node){if($node['column'] > $columns){$columns = $node['column']; // 總列數}}return $columns;}/*** 擷取分類的表格展現形式(不包含表頭)* */public function get_treetable(){$table_string = '';for($row = 1; $row <= $this->rows; $row++){$table_string .= "rt<tr>";foreach ($this->arr as $v){if($v['row'] == $row){$rowspan = $v['rowspan'] ? "rowspan='{$v['rowspan']}'" : '';$colspan = $v['colspan'] ? "colspan='{$v['colspan']}'" : '';$table_string .= "rtt<td {$rowspan} {$colspan}>{$v['name']}</td>";}}$table_string .= "rt</tr>";}return $table_string;}}?>
希望本文所述對大家學習php程式設計有所協助。