項目中會常常遇到須要遞歸的地方,分享一個正在用的一個遞歸查詢。雖然遞歸有時候會慢,可是尚未找到個好的解決辦法,若是有好的辦法,請分享一下。php
<?phpnamespace tree;use app\goods\model\Category;/** * 樹結構生成類 */class Tree{ /** * 根據父級id查詢全部父級id一下的全部分類 * @start */ static public $treeList = array(); // 存放無限級分類結果 static public function create($data,$pid = 0){ foreach ($data as $key => $value){ if($value['pid'] == $pid){ self::$treeList[] = $value; unset($data[$key]); self::create($data,$value['id']); } } return self::$treeList; } /** * 分類數據處理 * @end */ /** * @var object 對象實例 */ protected static $instance; /** * 配置參數 * @var array */ protected static $config = [ 'id' => 'id', // id名稱 'pid' => 'pid', // pid名稱 'title' => 'title', // 標題名稱 'child' => 'child', // 子元素鍵名 'html' => '┝ ', // 層級標記 'step' => 4, // 層級步進數量 ]; /** * 架構函數 * @param array $config */ public function __construct($config = []) { self::$config = array_merge(self::$config, $config); } /** * 配置參數 * @param array $config * @return object */ public static function config($config = []) { if (!empty($config)) { $config = array_merge(self::$config, $config); } if (is_null(self::$instance)) { self::$instance = new static($config); } return self::$instance; } /** * 將數據集格式化成層次結構 * @param array/object $lists 要格式化的數據集,能夠是數組,也能夠是對象 * @param int $pid 父級id * @param int $max_level 最多返回多少層,0爲不限制 * @param int $curr_level 當前層數 * @return array */ public static function toLayer($lists = [], $pid = 0, $max_level = 0, $curr_level = 0) { $trees = []; $lists = array_values($lists); foreach ($lists as $key => $value) { if ($value[self::$config['pid']] == $pid) { if ($max_level > 0 && $curr_level == $max_level) { return $trees; } unset($lists[$key]); $child = self::toLayer($lists, $value[self::$config['id']], $max_level, $curr_level + 1); if (!empty($child)) { $value[self::$config['child']] = $child; } $trees[] = $value; } } return $trees; } /** * 將數據集格式化成列表結構 * @param array|object $lists 要格式化的數據集,能夠是數組,也能夠是對象 * @param integer $pid 父級id * @param integer $level 級別 * @return array 列表結構(一維數組) */ public static function toList($lists = [], $pid = 0, $level = 0) { if (is_array($lists)) { $trees = []; foreach ($lists as $key => $value) { if ($value[self::$config['pid']] == $pid) { $title_prefix = str_repeat(" ", $level * self::$config['step']).self::$config['html']; $value['level'] = $level + 1; $value['title_prefix'] = $level == 0 ? '' : $title_prefix; $value['title_display'] = $level == 0 ? $value[self::$config['title']] : $title_prefix.$value[self::$config['title']]; $trees[] = $value; unset($lists[$key]); $trees = array_merge($trees, self::toList($lists, $value[self::$config['id']], $level + 1)); } } return $trees; } else { foreach ($lists as $key => $value) { if ($value[self::$config['pid']] == $pid && is_object($value)) { $title_prefix = str_repeat(" ", $level * self::$config['step']).self::$config['html']; $value['level'] = $level + 1; $value['title_prefix'] = $level == 0 ? '' : $title_prefix; $value['title_display'] = $level == 0 ? $value[self::$config['title']] : $title_prefix.$value[self::$config['title']]; $lists->offsetUnset($key); $lists[] = $value; self::toList($lists, $value[self::$config['id']], $level + 1); } } return $lists; } } /** * 根據子節點返回全部父節點 * @param array $lists 數據集 * @param string $id 子節點id * @return array */ public static function getParents($lists = [], $id = '') { $trees = []; foreach ($lists as $value) { if ($value[self::$config['id']] == $id) { $trees[] = $value; $trees = array_merge(self::getParents($lists, $value[self::$config['pid']]), $trees); } } return $trees; } /** * 獲取全部子節點id * @param array $lists 數據集 * @param string $pid 父級id * @return array */ public static function getChildsId($lists = [], $pid = '') { $result = []; foreach ($lists as $value) { if ($value[self::$config['pid']] == $pid) { $result[] = $value[self::$config['id']]; $result = array_merge($result, self::getChildsId($lists, $value[self::$config['id']])); } } return $result; } /** * 獲取全部子節點 * @param array $lists 數據集 * @param string $pid 父級id * @return array */ public static function getChilds($lists = [], $pid = '') { $result = []; foreach ($lists as $value) { if ($value[self::$config['pid']] == $pid) { $result[] = $value; $result = array_merge($result, self::getChilds($lists, $value[self::$config['id']])); } } return $result; } /** * 根據子分類獲取頂級分類 * @param string $id 子分類id * @return int */ public static function getNavPid($id){ $catId = Category::get($id); if($catId['pid'] != 0){ return self::getNavPid($catId['pid']); } return $catId['id']; }}