传入简单的原始数据,可以得出节点间的n种关系,并能输出树状的dom
注意:请参考git.oschina.net上的最新代码(点源码出处链接) 1, 'name' => '栏目分类_1', 'name_en' => 'cat_1', 'parent_id' => 0), array('id' => 2, 'name' => '栏目分类_2', 'name_en' => 'cat_2', 'parent_id' => 0), array('id' => 3, 'name' => '栏目分类_3', 'name_en' => 'cat_3', 'parent_id' => 1), array('id' => 4, 'name' => '栏目分类_4', 'name_en' => 'cat_4', 'parent_id' => 1), array('id' => 5, 'name' => '栏目分类_5', 'name_en' => 'cat_5', 'parent_id' => 2), array('id' => 6, 'name' => '栏目分类_6', 'name_en' => 'cat_6', 'parent_id' => 4), array('id' => 7, 'name' => '栏目分类_7', 'name_en' => 'cat_7', 'parent_id' => 6), array('id' => 8, 'name' => '栏目分类_8', 'name_en' => 'cat_8', 'parent_id' => 7), array('id' => 9, 'name' => '栏目分类_9', 'name_en' => 'cat_9', 'parent_id' => 6));$objt = new treelist($arrall);print_r($objt->arrall);print_r($objt->arridall);print_r($objt->arridchildren);print_r($objt->arridson);print_r($objt->arridleaf);print_r($objt->arridrelation);print_r($objt->arridrelationsimple);print_r($objt->arridroot);print_r($objt->arridbackpath);print($objt->gettable());print($objt->getselect('cat', array(1, 8), true));*/// !defined('in_frame') && die('404 page');class treelist { /** * 分析出所有可能用到的数据 */ public $arrall = array(); // 原始数据 public $arridrelation = array(); // 按_id作键名的多维关系 public $arridrelationsimple = array(); // 按_id作键名的多维关系的简化,用来输出树状图 public $arridall = array(); // 将原始数据转化成的_id作键名的数组 public $arridson = array(); // 所有的父子关系 public $arridleaf = array(); // 叶子节点的_id public $arridroot = array(); // 根节点的_id public $arridchildren = array(); // 每个节点下的子孙后代_id public $arridbackpath = array(); // 每个节点回逆到根 public $stritem = '
{$strsep}{$name}'; // 输出树的结构 /** * 构造函数,传入原始数据 */ public function __construct($arrdata) { $this->arrall = $arrdata; $this->processdata(); } /** * 简单的树 */ public function gethtml() { return $this->genhtml(); } /** * 用table来画树 */ public function gettable() { $this->stritem = '{$strsep}{$name} {$name} {$name_en}
'; $strre = ''; $strre .= '结构中文名英文名
'; $strre .= $this->genhtml(); $strre .= '
'; return $strre; } /** * 在下拉框中显示 * example: * $objtreelist->getselect('parent_id', 0, false, 'class=span5', array(0, '≡ 作为一级栏目 ≡'))) */ public function getselect($strname = 'tree', $arrvalue = array(), $blmmulti = false, $strext = '', $arrfirst = null) { !is_array($arrvalue) && $arrvalue = array($arrvalue); foreach ($this->arridall as $strtemp => $arrtemp) { $this->arridall[$strtemp]['selected'] = ''; if (in_array($arrtemp['id'], $arrvalue)) { $this->arridall[$strtemp]['selected'] = ' selected=selected'; } } $this->stritem = '{$strsep}{$name}'; $strre = ' $strre .= ($blmmulti ? ' multiple=multiple' : '') . (empty($strext) ? '' : ' ' . $strext) . '>'; if (is_array($arrfirst) && count($arrfirst) == 2) { $strre .= '' . $arrfirst[1] . ''; } $strre .= $this->gethtml() . ''; return $strre; } /* ----- 以下的都是处理数据的私有函数,递归和循环之类,很复杂! ----- */ private function helpforgetrelation($arrdata) { $arrre = array(); foreach ($arrdata as $strtemp => $arrtemp) { $arrre[$strtemp] = $arrtemp; if (isset($this->arridrelation[$strtemp])) { $arrre[$strtemp] = $this->arridrelation[$strtemp]; } if (count($arrre[$strtemp]) > 0) { $arrre[$strtemp] = $this->helpforgetrelation($arrre[$strtemp]); } else { array_push($this->arridleaf, $strtemp); } } return $arrre; } private function helpforgetchildren($arrdata) { $arrre = array_keys($arrdata); foreach ($arrdata as $arrtemp) { $arrre = array_merge($arrre, $this->helpforgetchildren($arrtemp)); } return $arrre; } private function helpforgetbackpath($str) { $arrre = array(); $inttemp = $this->arridall[$str]['parent_id']; if ($inttemp > 0) { $inttemp = '_' . $inttemp; array_push($arrre, $inttemp); $arrre = array_merge($arrre, $this->helpforgetbackpath($inttemp)); } return $arrre; } private function processdata() { foreach ($this->arrall as $arrtemp) { $strtemp = '_' . $arrtemp['id']; $this->arridall[$strtemp] = $arrtemp; if ($arrtemp['parent_id'] > 0) { $strtemp_ = '_' . $arrtemp['parent_id']; !isset($this->arridrelation[$strtemp_]) && $this->arridrelation[$strtemp_] = array(); $this->arridrelation[$strtemp_][$strtemp] = array(); !isset($this->arridson[$strtemp_]) && $this->arridson[$strtemp_] = array(); array_push($this->arridson[$strtemp_], $strtemp); } else { !isset($this->arridrelation[$strtemp]) && $this->arridrelation[$strtemp] = array(); array_push($this->arridroot, $strtemp); } } $this->arridrelation = $this->helpforgetrelation($this->arridrelation); $this->arridleaf = array_unique($this->arridleaf); foreach ($this->arridrelation as $strtemp => $arrtemp) { $this->arridchildren[$strtemp] = $this->helpforgetchildren($arrtemp); in_array($strtemp, $this->arridroot) && $this->arridrelationsimple[$strtemp] = $arrtemp; } $arrtemp = array_keys($this->arridall); foreach ($arrtemp as $strtemp) { $this->arridbackpath[$strtemp] = $this->helpforgetbackpath($strtemp); } } private function genseparator($intlen) { $strre = ''; $i = 0; while ($i $strre .= ' ' . (($i + 1 == $intlen) ? '├' : '│'); $i ++; } !empty($strre) && $strre .= '─'; return $strre; } private function genhtml($arrrelation = null, $intsep = 0) { $strre = ''; null === $arrrelation && $arrrelation = $this->arridrelationsimple; foreach ($arrrelation as $strkey => $arrtemp) { if (count($this->arridall[$strkey]) > 0) { $strsep = $this->genseparator($intsep); extract($this->arridall[$strkey]); eval('$strre .= ' . $this->stritem . ';'); count($arrtemp) > 0 && $strre .= $this->genhtml($arrtemp, ($intsep + 1)); } } return $strre; }}
复制代码