// +---------------------------------------------------------------------- declare(strict_types=1); namespace App\Support; class Tree{ protected $formatTree; /** * 把返回的数据集转换成Tree * @param array $list 要转换的数据集 * @param string $pid parent标记字段 * @param string $level level标记字段 * @return array * @author 麦当苗儿 */ public function listToTree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0) { // 创建Tree $tree = array(); if (is_array($list)) { // 创建基于主键的数组引用 $refer = array(); foreach ($list as $key => $data) { $refer[$data[$pk]] = &$list[$key]; } foreach ($list as $key => $data) { // 判断是否存在parent $parentId = $data[$pid]; if ($root == $parentId) { $tree[] = &$list[$key]; } else { if (isset($refer[$parentId])) { $parent = &$refer[$parentId]; $parent['childs'][] = $data['id']; $parent[$child][] = &$list[$key]; } } } } return $tree; } /** * 获得所有的子 * @param [type] $id [description] * @return [type] [description] */ public function getChilds($data, $id = 0, $pk = 'id', $pid = 'pid') { $array = []; foreach ($data as $k => $v) { if ($v[$pid] == $id) { $array[] = $v[$pk]; array_merge($array, $this->getChilds($data, $v[$pk])); } } return $array; } /** * 获取id的所有父,包含自己 * @param [type] $id [description] * @return [type] [description] */ public function getParents($data, $id = 0, $pk = 'id', $pid = 'pid') { static $ids = []; foreach ($data as $k => $v) { if ($v[$pk] == $id) { array_unshift($ids, $id); if ($v['pid'] == 0) { break; } $this->getParents($data, $v[$pid]); } } return $ids; } /** * 将树子节点加层级成列表 * @param [type] $tree [description] * @param integer $level [description] * @return [type] [description] */ protected function _toFormatTree($tree, $level = 1) { foreach ($tree as $key => $value) { $temp = $value; if (isset($temp['_child'])) { $temp['_child'] = true; $temp['level'] = $level; } else { $temp['_child'] = false; $temp['level'] = $level; } array_push($this->formatTree, $temp); if (isset($value['_child'])) { $this->_toFormatTree($value['_child'], ($level + 1)); } } } protected function catEmptyDeal($cat, $next_parentid, $pid = 'pid', $empty = "    ") { $str = ""; if ($cat[$pid]) { for ($i = 2; $i < $cat['level']; $i++) { $str .= $empty . "│"; } if ($cat[$pid] != $next_parentid && !$cat['_child']) { $str .= $empty . "└─ "; } else { $str .= $empty . "├─ "; } } return $str; } /** * 格式化树 * @param [type] $list [description] * @param string $title [description] * @param string $pk [description] * @param string $pid [description] * @param integer $root [description] * @return [type] [description] */ public function toFormatTree($list, $title = 'title', $pk = 'id', $pid = 'pid', $root = 0) { if (empty($list)) { return false; } $list = $this->listToTree($list, $pk, $pid, '_child', $root); $this->formatTree = array(); $this->_toFormatTree($list); $data = array(); foreach ($this->formatTree as $key => $value) { $index = ($key + 1); $next_parentid = isset($this->formatTree[$index][$pid]) ? $this->formatTree[$index][$pid] : ''; $value['level_show'] = $this->catEmptyDeal($value, $next_parentid); $value['title_show'] = $value['level_show'] . $value[$title]; $data[] = $value; } return $data; } }