PHP 无限级缩进分类
PHP 无限极分类经常被使用应用,如菜单无限极分类,国家省市级分类,商城等等
核心类
比如在TP6中使用 代码路径
项目文件夹/extend 新建 holyrisk文件夹 Tree.php
<?php namespace holyrisk; class Tree { /** * @description 无限极分类实现 - 嵌套形式 * @author Holyrisk * @date 2021/4/22 22:41 * @param $list 需要被处理的数组 * @param string $pk id * @param string $pid 父级id * @param string $child 子级名称 * @param int $root 顶级分类的值 * @return array */ public function buildTree($list, $pk='id', $pid='pid', $child='children', $root=0){ if (empty($list)){ return []; } $tree = array(); $packData = array(); foreach ($list as $data) { $packData[$data[$pk]] = $data; } foreach ($packData as $key=>$val){ if($val[$pid] == $root){ $tree[] = &$packData[$key]; }else{ $packData[$val[$pid]][$child][] = &$packData[$key]; } } return $tree; } /** * 无限极分类实现 - 列表形式 取得等级 级别 * @param $array 分类数据 * @param $pid 父ID * @param $level 分类级别 * @return array 分好类的数组 直接遍历即可 $level可以用来遍历缩进 */ public function getTreeLevel($array, $pid =0, $level = 0){ //声明静态数组,避免递归调用时,多次声明导致数组覆盖 static $list = []; foreach ($array as $key => $value){ //第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点 if ($value['pid'] == $pid){ //父节点为根节点的节点,级别为0,也就是第一级 $value['level'] = $level; //把数组放到list中 $list[] = $value; //把这个节点从数组中移除,减少后续递归消耗 unset($array[$key]); //开始递归,查找父ID为该节点ID的节点,级别则为原级别+1 $this->getTreeLevel($array, $value['id'], $level+1); } } return $list; } /** * 缩进形式 无限级 分类 * 参考 https://www.cnblogs.com/phpk/p/10929918.html * @param $array * @param int $pid * @param int $level * @return array */ public function getTreeHtmlSelect($array, $pid =0, $level = 0) { $list = $this->getTreeLevel($array,$pid,$level); foreach ($list as $key => $value){ $list[$key]['name'] = str_repeat('>>', $value['level']). $value['name']; } return $list; } }
代码调用演示
use holyrisk\Tree; $array = array( array('id' => 1, 'pid' => 0, 'name' => '河北省'), array('id' => 2, 'pid' => 0, 'name' => '北京市'), array('id' => 3, 'pid' => 1, 'name' => '邯郸市'), array('id' => 4, 'pid' => 2, 'name' => '朝阳区'), array('id' => 5, 'pid' => 2, 'name' => '通州区'), array('id' => 6, 'pid' => 4, 'name' => '望京'), array('id' => 7, 'pid' => 4, 'name' => '酒仙桥'), array('id' => 8, 'pid' => 3, 'name' => '永年区'), array('id' => 9, 'pid' => 1, 'name' => '武安市'), ); $son = (new Tree())->buildTree($array); $list = (new Tree())->getTreeLevel($array); $arr = (new Tree())->getTreeHtmlSelect($array); echo "<pre>"; echo "原始数据"."<br />"; echo print_r($array); echo "嵌套形式"."<br />"; echo print_r($son); echo "列表级别形式"."<br />"; echo print_r($list); echo "列表缩进 - 给HTML下拉框使用形式"."<br />"; echo print_r($arr); echo "</pre>";
输出打印
原始数据 Array ( [0] => Array ( [id] => 1 [pid] => 0 [name] => 河北省 ) [1] => Array ( [id] => 2 [pid] => 0 [name] => 北京市 ) [2] => Array ( [id] => 3 [pid] => 1 [name] => 邯郸市 ) [3] => Array ( [id] => 4 [pid] => 2 [name] => 朝阳区 ) [4] => Array ( [id] => 5 [pid] => 2 [name] => 通州区 ) [5] => Array ( [id] => 6 [pid] => 4 [name] => 望京 ) [6] => Array ( [id] => 7 [pid] => 4 [name] => 酒仙桥 ) [7] => Array ( [id] => 8 [pid] => 3 [name] => 永年区 ) [8] => Array ( [id] => 9 [pid] => 1 [name] => 武安市 ) ) 1嵌套形式 Array ( [0] => Array ( [id] => 1 [pid] => 0 [name] => 河北省 [children] => Array ( [0] => Array ( [id] => 3 [pid] => 1 [name] => 邯郸市 [children] => Array ( [0] => Array ( [id] => 8 [pid] => 3 [name] => 永年区 ) ) ) [1] => Array ( [id] => 9 [pid] => 1 [name] => 武安市 ) ) ) [1] => Array ( [id] => 2 [pid] => 0 [name] => 北京市 [children] => Array ( [0] => Array ( [id] => 4 [pid] => 2 [name] => 朝阳区 [children] => Array ( [0] => Array ( [id] => 6 [pid] => 4 [name] => 望京 ) [1] => Array ( [id] => 7 [pid] => 4 [name] => 酒仙桥 ) ) ) [1] => Array ( [id] => 5 [pid] => 2 [name] => 通州区 ) ) ) ) 1列表级别形式 Array ( [0] => Array ( [id] => 1 [pid] => 0 [name] => 河北省 [level] => 0 ) [1] => Array ( [id] => 3 [pid] => 1 [name] => 邯郸市 [level] => 1 ) [2] => Array ( [id] => 8 [pid] => 3 [name] => 永年区 [level] => 2 ) [3] => Array ( [id] => 9 [pid] => 1 [name] => 武安市 [level] => 1 ) [4] => Array ( [id] => 2 [pid] => 0 [name] => 北京市 [level] => 0 ) [5] => Array ( [id] => 4 [pid] => 2 [name] => 朝阳区 [level] => 1 ) [6] => Array ( [id] => 6 [pid] => 4 [name] => 望京 [level] => 2 ) [7] => Array ( [id] => 7 [pid] => 4 [name] => 酒仙桥 [level] => 2 ) [8] => Array ( [id] => 5 [pid] => 2 [name] => 通州区 [level] => 1 ) ) 1列表缩进 - 给HTML下拉框使用形式 Array ( [0] => Array ( [id] => 1 [pid] => 0 [name] => 河北省 [level] => 0 ) [1] => Array ( [id] => 3 [pid] => 1 [name] => >>邯郸市 [level] => 1 ) [2] => Array ( [id] => 8 [pid] => 3 [name] => >>>>永年区 [level] => 2 ) [3] => Array ( [id] => 9 [pid] => 1 [name] => >>武安市 [level] => 1 ) [4] => Array ( [id] => 2 [pid] => 0 [name] => 北京市 [level] => 0 ) [5] => Array ( [id] => 4 [pid] => 2 [name] => >>朝阳区 [level] => 1 ) [6] => Array ( [id] => 6 [pid] => 4 [name] => >>>>望京 [level] => 2 ) [7] => Array ( [id] => 7 [pid] => 4 [name] => >>>>酒仙桥 [level] => 2 ) [8] => Array ( [id] => 5 [pid] => 2 [name] => >>通州区 [level] => 1 ) [9] => Array ( [id] => 1 [pid] => 0 [name] => 河北省 [level] => 0 ) [10] => Array ( [id] => 3 [pid] => 1 [name] => >>邯郸市 [level] => 1 ) [11] => Array ( [id] => 8 [pid] => 3 [name] => >>>>永年区 [level] => 2 ) [12] => Array ( [id] => 9 [pid] => 1 [name] => >>武安市 [level] => 1 ) [13] => Array ( [id] => 2 [pid] => 0 [name] => 北京市 [level] => 0 ) [14] => Array ( [id] => 4 [pid] => 2 [name] => >>朝阳区 [level] => 1 ) [15] => Array ( [id] => 6 [pid] => 4 [name] => >>>>望京 [level] => 2 ) [16] => Array ( [id] => 7 [pid] => 4 [name] => >>>>酒仙桥 [level] => 2 ) [17] => Array ( [id] => 5 [pid] => 2 [name] => >>通州区 [level] => 1 ) )