无限极分类数组的处理类 [ 未指定版本 ]
第一次在Yii论坛上分享自己的代码,请大家多多关照。
下面我分享一个在平时做项目的时候封装的类。这个类专门用来处理二维无限分类数组(比如省市的列表,有id和pid两个属性,其中pid是父分类的id)。各个成员函数的用途已经在注释里面做了详细的说明。
<?php
/**
* 无限极分类-二维无限分类数组处理类
**/
class Category
{
//无限分类数组,其中必须要有id和pid
public static $list = [];
//id => pid 数组
private static $_sp_list = [];
//子分类key
private static $_sk;
//父分类key
private static $_pk;
/**
*对数组进行初始化处理
* $cat_list 无限分类数组
* $skey 数组中子分类的key值
* $pkey 数组中父分类的key值
* @return mixed array
**/
public function __construct($cat_list, $skey = 'id', $pkey = 'pid')
{
parent::init();
self::$_sk = $skey;
self::$_pk = $pkey;
$this->init($cat_list);
}
/**
*对数组进行初始化处理
* @return mixed array
**/
public function init($cat_list)
{
if (empty($cat_list))
{
return false;
}
//对数组进行预处理
foreach ($cat_list as $key => $val)
{
//生成sid => pid 数组
self::$_sp_list[$val[self::$_sk]] = $val[self::$_pk];
//以数组的子分类值作为索引
self::$list[$val[self::$_sk]] = $val;
}
unset($cat_list);
}
/**
* 获取格式化的树形数据
* @param $pid int $list中顶级分类id
* @param $level int $list中顶级分类的层级
* @param $html string 上下层级之间的标示符号
* @return mixed
**/
public static function sort($pid = 0, $level = 0, $html = '-')
{
if (empty(self::$list))
{
return false;
}
static $tree = array();
foreach (self::$list as $v)
{
if ($v[self::$_pk] == $pid)
{
$v['sort'] = $level + 1;
$v['html'] = str_repeat($html, $level);
$tree[$v[self::$_sk]] = $v;
self::sort($v[self::$_sk], $level + 1);
}
}
return $tree;
}
/**
* 获取分类的无限极子分类,以树型结构显示
* @param $son string 子节点节点名
* @return mixed
**/
public static function tree($son = 'son')
{
if (empty(self::$list))
{
return false;
}
$list = self::$list;
foreach ($list as $item)
{
$list[$item[self::$_pk]][$son][$item[self::$_sk]] = &$list[$item[self::$_sk]];
}
return isset($list[0][$son]) ? $list[0][$son] : array();
}
/**
* 获取分类的祖先分类
* @param $id int 分类id
* @param $type bool true-返回祖先分类数组 false-返回祖先分类id
* @return mixed
**/
public static function ancestor($id, $type = true)
{
if (empty(self::$list) || empty(self::$_sp_list))
{
return false;
}
while (self::$_sp_list[$id])
{
$id = self::$_sp_list[$id];
}
return $type && isset(self::$list[$id]) ? self::$list[$id] : $id;
}
/**
* 获取所有父级分类对应层级关系
* @param $id int 分类id
* @param $type bool true-返回分类数组 false-返回分类id
* @return mixed
**/
public static function parents($id, $type = true)
{
if (empty(self::$list))
{
return false;
}
$info = [];
while (isset(self::$_sp_list[$id]))
{
$info[] = $type ? self::$list[$id] : $id;
$id = self::$_sp_list[$id];
}
return $info;
}
/**
* 获取所有子级分类对应层级关系
* @param $id int 子分类id
* @param $type bool true-返回分类数组 false-返回分类id
* @return mixed
**/
public static function sons($id, $type = true)
{
if (empty(self::$list))
{
return false;
}
static $info = [];
foreach (self::$list as $val)
{
if ($val[self::$_pk] == $id)
{
$info[$val[self::$_sk]] = $type ? $val : $val[self::$_sk];
if (self::has_son($val[self::$_sk]))
{
self::sons($val[self::$_sk], $type);
}
}
}
return $info;
}
/**
* 获取所有儿子分类
* @param $p_id int 父id
* @param $type bool true-返回分类数组 false-返回分类id
* @return mixed
**/
public static function son($p_id = 0, $type = true)
{
if (empty(self::$list))
{
return false;
}
$_arr = [];
foreach (self::$list as $val)
{
if ($val[self::$_pk] == $p_id)
{
$_arr[$val[self::$_sk]] = $type ? $val : $val[self::$_sk];
}
}
return $_arr;
}
/**
* 是否含有子分类,是否是叶子节点
* @param $pid int 父分类id
* @return mixed
**/
public static function has_son($pid)
{
if (empty(self::$list) || empty(self::$_sp_list))
{
return false;
}
return in_array($pid, array_values(self::$_sp_list));
}
}
获取省市关系举例:
假如省市关系以无限级的二维形式存与数据库中,
$list = Array
(
[1] => Array
(
[id] => 1
[pid] => 0
[name] => 北京市
)
[2] => Array
(
[id] => 2
[pid] => 0
[name] => 上海市
)
....
[5] => Array
(
[id] => 5
[pid] => 0
[name] => 河北省
)
....
[44] => Array
(
[id] => 44
[pid] => 5
[name] => 廊坊市
)
[45] => Array
(
[id] => 45
[pid] => 5
[name] => 衡水市
)
....
}
可以将这个数组取出放在缓存当中,每次获取时从缓存获取。获取后首先初始化:
$cat = new Category($list);
1.获取省市树形结构数据
$_city_tree = $cat::tree();结果为
Array
(
[1] => Array
(
[id] => 1
[pid] => 0
[name] => 北京市
[son] => Array
(
[415] => Array
(
[id] => 415
[pid] => 1
[name] => 北京市
)
)
)
....
[5] => Array
(
[id] => 5
[pid] => 0
[name] => 河北省
[son] => Array
(
....
[44] => Array
(
[id] => 44
[pid] => 5
[name] => 廊坊市
)
[45] => Array
(
[id] => 45
[pid] => 5
[name] => 衡水市
)
)
)
....
}
2.获取可以直接用于显示的格式化的数据:
$_city_html = $cat::sort(0, 0, '--');结果为
Array
(
[1] => Array
(
[id] => 1
[pid] => 0
[name] => 北京市
[sort] => 1
[html] =>
)
[415] => Array
(
[id] => 415
[pid] => 1
[name] => 北京市
[sort] => 2
[html] => -
)
....
[5] => Array
(
[id] => 5
[pid] => 0
[name] => 河北省
[sort] => 1
[html] =>
)
....
[44] => Array
(
[id] => 44
[pid] => 5
[name] => 廊坊市
[sort] => 2
[html] => -
)
[45] => Array
(
[id] => 45
[pid] => 5
[name] => 衡水市
[sort] => 2
[html] => -
)
....
}
这个类在使用时,还需需要加上命名空间,如果想要绑定事件,还要继承\yii\base\Component。
欢迎大家对这个类做有益的补充~~
37371
注册时间:2016-10-31
最后登录:1970-01-01
在线时长:0小时0分
最后登录:1970-01-01
在线时长:0小时0分
- 粉丝7
- 金钱35
- 威望20
- 积分235
热门源码
- 基于 Yii 2 + Bootstrap 3 搭建一套后台管理系统 CMF
- 整合完 yii2-rbac+yii2-admin+adminlte 等库的基础开发后台源码
- 适合初学者学习的一款通用的管理后台
- yii-goaop - 将 goaop 集成到 Yii,在 Yii 中优雅的面向切面编程
- yii-log-target - 监控系统异常且多渠道发送异常信息通知
- 店滴云1.3.0
- 面向对象的一小步:添加 ActiveRecord 的 Scope 功能
- Yii2 开源商城 FecShop
- 基于 Yii2 开发的多店铺商城系统,免费开源 + 适合二开
- leadshop - 基于 Yii2 开发的一款免费开源且支持商业使用的商城管理系统
共 4 条评论
谢谢......
多多交流,一起进步~~
function genTree($items) { foreach ($items as $item){ $items[$item['pid']]['son'][$item['id']] = &$items[$item['id']]; } return isset($items[0]['son']) ? $items[0]['son'] : array(); }
简单的实现
是的额,这个实现非常的简洁,高效!
@37371 太酷了!!!!!EXCITE!!!!
public static function getRegionCode($code){ $data = self::find()->all(); $data = ArrayHelper::map($data, 'id','superID'); $data=self::findOne($data[$code]); return $data['name']; } public static function getRegion($id){ $data = self::find()->all(); $data = ArrayHelper::map($data, 'id','name'); return $data[$id]; }
看着静态属性,静态方法有些别扭,我替换掉了;
<?php /** * 无限极分类-二维无限分类数组处理类 * **/ class MultiCat { //无限分类数组,其中必须要有id和pid public $list = []; //id => pid 数组 private $_sp_list = []; //子分类key private $_sk; //父分类key private $_pk; /** *对数组进行初始化处理 * $cat_list 无限分类数组 * $skey 数组中子分类的key值 * $pkey 数组中父分类的key值 * @return mixed array **/ public function __construct($cat_list, $skey = 'id', $pkey = 'pid') { //parent::init(); $this->_sk = $skey; $this->_pk = $pkey; $this->init($cat_list); } /** *对数组进行初始化处理 * @return mixed array **/ public function init($cat_list) { if (empty($cat_list)) { return false; } //对数组进行预处理 foreach ($cat_list as $key => $val) { //生成sid => pid 数组 $this->_sp_list[$val[$this->_sk]] = $val[$this->_pk]; //以数组的子分类值作为索引 $this->list[$val[$this->_sk]] = $val; } unset($cat_list); } /** * 获取格式化的树形数据 * @param $pid int $list中顶级分类id * @param $level int $list中顶级分类的层级 * @param $html string 上下层级之间的标示符号 * @return mixed **/ public function sort($pid = 0, $level = 0, $html = '-') { if (empty($this->list)) { return false; } static $tree = array(); foreach ($this->list as $v) { if ($v[$this->_pk] == $pid) { $v['sort'] = $level + 1; $v['html'] = str_repeat($html, $level); $tree[$v[$this->_sk]] = $v; $this->sort($v[$this->_sk], $level + 1); } } return $tree; } /** * 获取分类的无限极子分类,以树型结构显示 * @param $son string 子节点节点名 * @return mixed **/ public function tree($son = 'son') { if (empty($this->list)) { return []; } $list = $this->list; foreach ($list as $item) { $list[$item[$this->_pk]][$son][$item[$this->_sk]] = &$list[$item[$this->_sk]]; } return isset($list[0][$son]) ? $list[0][$son] : array(); } /** * 获取分类的祖先分类 * @param $id int 分类id * @param $type bool true-返回祖先分类数组 false-返回祖先分类id * @return mixed **/ public function ancestor($id, $type = true) { if (empty($this->list) || empty($this->_sp_list)) { return false; } while ($this->_sp_list[$id]) { $id = $this->_sp_list[$id]; } return $type && isset($this->list[$id]) ? $this->list[$id] : $id; } /** * 获取所有父级分类对应层级关系 * @param $id int 分类id * @param $type bool true-返回分类数组 false-返回分类id * @return mixed **/ public function parents($id, $type = true) { if (empty($this->list)) { return false; } $info = []; while (isset($this->_sp_list[$id])) { $info[] = $type ? $this->list[$id] : $id; $id = $this->_sp_list[$id]; } return $info; } /** * 获取所有子级分类对应层级关系 * @param $id int 子分类id * @param $type bool true-返回分类数组 false-返回分类id * @return mixed **/ public function sons($id, $type = true) { if (empty($this->list)) { return false; } static $info = []; foreach ($this->list as $val) { if ($val[$this->_pk] == $id) { $info[$val[$this->_sk]] = $type ? $val : $val[$this->_sk]; if (self::has_son($val[$this->_sk])) { self::sons($val[$this->_sk], $type); } } } return $info; } /** * 获取所有儿子分类 * @param $p_id int 父id * @param $type bool true-返回分类数组 false-返回分类id * @return mixed **/ public function son($p_id = 0, $type = true) { if (empty($this->list)) { return false; } $_arr = []; foreach ($this->list as $val) { if ($val[$this->_pk] == $p_id) { $_arr[$val[$this->_sk]] = $type ? $val : $val[$this->_sk]; } } return $_arr; } /** * 是否含有子分类,是否是叶子节点 * @param $pid int 父分类id * @return mixed **/ public function has_son($pid) { if (empty($this->list) || empty($this->_sp_list)) { return false; } return in_array($pid, array_values($this->_sp_list)); } }
调用DEMO还是用你的:
$cat_list = [ ['id' => 1, 'pid' => 0, 'name' => "北京市",], ['id' => 2, 'pid' => 0, 'name' => "上海市",], //... ['id' => 5, 'pid' => 0, 'name' => "河北省",], ['id' => 43, 'pid' => 5, 'name' => "衡水市",], ['id' => 44, 'pid' => 5, 'name' => "廊坊市",], //... ['id' => 100, 'pid' => 44, 'name' => "三河市",], ['id' => 101, 'pid' => 44, 'name' => "香河市",], ['id' => 133, 'pid' => 100, 'name' => "燕郊镇",], ]; $cat = new MultiCat($cat_list); $_city_tree = $cat->tree(); $_city_html = $cat->sort(0, 0, '-'); VarDumper::dump($_city_tree); VarDumper::dump($_city_html);