php 实现无限极分类
原始数据
$array = array(
array('id' => 1, 'pid' => 0, 'n' => '河北省'),
array('id' => 2, 'pid' => 0, 'n' => '北京市'),
array('id' => 3, 'pid' => 1, 'n' => '邯郸市'),
array('id' => 4, 'pid' => 2, 'n' => '朝阳区'),
array('id' => 5, 'pid' => 2, 'n' => '通州区'),
array('id' => 6, 'pid' => 4, 'n' => '望京'),
array('id' => 7, 'pid' => 4, 'n' => '酒仙桥'),
array('id' => 8, 'pid' => 3, 'n' => '永年区'),
array('id' => 9, 'pid' => 1, 'n' => '武安市'),
array('id' => 10, 'pid' => 8, 'n' => '永年区镇'),
array('id' => 11, 'pid' => 0, 'n' => '上海市')
);
生成无限极分类
/** 所有的分类
* @parem $array 数组
* @parem $pid ,最高级别,默认为0,输出从pid 级别的数据
* @parem $level 层级,默认0
* */
function getTree($array, $pid =0, $level = 0){ $f_name=__FUNCTION__; // 定义当前函数名 //声明静态数组,避免递归调用时,多次声明导致数组覆盖
static $list = []; foreach ($array as $key => $value){
//第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点
if ($value['pid'] == $pid){
//父节点为根节点的节点,级别为0,也就是第一级
$flg = str_repeat('|--',$level);
// 更新 名称值
$value['n'] = $flg.$value['n'];
// 输出 名称
echo $value['n']."<br/>";
//把数组放到list中
$list[] = $value;
//把这个节点从数组中移除,减少后续递归消耗
unset($array[$key]);
//开始递归,查找父ID为该节点ID的节点,级别则为原级别+1
$f_name($array, $value['id'], $level+1);
}
}
return $list;
}
// 调用
$list=getTree($array);
调用结果:
河北省
|--邯郸市
|--|--永年区
|--|--|--永年区镇
|--武安市
北京市
|--朝阳区
|--|--望京
|--|--酒仙桥
|--通州区
嵌套标签,前端可以(通过选取子节点)全选、取消全选
function getTree($array, $pid =0, $level = 0){ $f_name=__FUNCTION__; // 定义当前函数名 // 空数组 不在执行
if(empty($array))
return; //声明静态数组,避免递归调用时,多次声明导致数组覆盖
static $html;
$html.="<ul>"; foreach ($array as $key => $value){ //第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点
if ($value['pid'] == $pid){
//父节点为根节点的节点,级别为0,也就是第一级
$flg = str_repeat('|--',$level);
// 更新 名称值
$value['n'] = $flg.$value['n'];
$html.=$temp="<li><input type=\"checkbox\" name=\"limit_id[]\" value='".$value['id']."' >".$value['n']; //把这个节点从数组中移除,减少后续递归消耗
unset($array[$key]);
//开始递归,查找父ID为该节点ID的节点,级别则为原级别+1
$vv=$f_name($array, $value['id'], $level+1); // 如果顶级分类下没有一个下级,删除此分类,此步骤可以省略
if(empty($vv) && ($pid<1))
{
$html=str_replace($temp,'',$html);
}
$html.="</li>\r\n"; }
}
$html.="</ul>\r\n"; // 删除多余的 ul 标签
$html=str_replace("<ul></ul>",'',$html);
return $html;
}
html 输出结果
<ul>
<li><input type="checkbox" name="limit_id[]" value='1'>河北省
<ul>
<li><input type="checkbox" name="limit_id[]" value='3'>|--邯郸市
<ul>
<li><input type="checkbox" name="limit_id[]" value='8'>|--|--永年区
<ul>
<li><input type="checkbox" name="limit_id[]" value='10'>|--|--|--永年区镇
</li>
</ul>
</li>
</ul>
</li>
<li><input type="checkbox" name="limit_id[]" value='9'>|--武安市
</li>
</ul>
</li>
<li><input type="checkbox" name="limit_id[]" value='2'>北京市
<ul>
<li><input type="checkbox" name="limit_id[]" value='4'>|--朝阳区
<ul>
<li><input type="checkbox" name="limit_id[]" value='6'>|--|--望京
</li>
<li><input type="checkbox" name="limit_id[]" value='7'>|--|--酒仙桥
</li>
</ul>
</li>
<li><input type="checkbox" name="limit_id[]" value='5'>|--通州区
</li>
</ul>
</li>
</li>
</ul>
jquery 操作全选
//父级选中 自动选中子级,同时选中自己的父级
$('input[type="checkbox"]').change(function(e) {
var checked = $(this).prop("checked"),
container = $(this).parent(),
siblings = container.siblings(); container.find('input[type="checkbox"]').prop({
indeterminate: false,
checked: checked
}); function checkSiblings(el) { var parent = el.parent().parent(),
all = true; el.siblings().each(function() {
return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked);
}); if (all && checked) { parent.children('input[type="checkbox"]').prop({
indeterminate: false,
checked: checked
}); checkSiblings(parent); } else if (all && !checked) { parent.children('input[type="checkbox"]').prop("checked", checked);
parent.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0));
checkSiblings(parent); } else { el.parents("li").children('input[type="checkbox"]').prop({
indeterminate: true,
checked: false
}); } }
checkSiblings(container);
});
// 父级选中 自动选中子级
/*$("input[type=checkbox]").each(function (i,ele){
let _this=$(this);
_this.click(function(){
if(_this.prop('checked')==true)
{
_this.parent().find('ul input').prop('checked',true);
}else
{
_this.parent().find('ul input').prop('checked',false);
}
});
});*/
数组嵌套
引用嵌套,php变量默认的传值方式是按指传递,也就是说 假如说 遍历顺序是 河北省 邯郸市 当遍历到河北省时需要把河北省放到tree中,遍历到邯郸市时,需要把邯郸市放到河北省的子节点数组中,所以这里用到了引用传递,当你对河北省做更改时,tree数组中的河北省也一并做了更改
function getTree($list, $pid = 0)
{
$tree = [];
if (!empty($list)) {
$newList = []; foreach ($list as $k => $v) {
$newList[$v['id']] = $v;
}
foreach ($newList as $value ) {
if ($pid == $value['pid']) {
$tree[] = &$newList[$value['id']];
} elseif (isset($newList[$value['pid']]))
{
$newList[$value['pid']]['items'][] = &$newList[$value['id']];
}
}
// 如果顶级分类下没有一个下级,删除此分类,此步骤可以省略
foreach ($tree as $k=>$v)
{
if(!isset($v['items']) && ($pid<1))
unset($tree[$k]);
}
}
return $tree;
}
// 调用
$list=getTree($array);
var_dump($list);
显示结果
array(2) {
[0]=>
array(4) {
["id"]=>
int(1)
["pid"]=>
int(0)
["n"]=>
string(9) "河北省"
["items"]=>
array(2) {
[0]=>
array(4) {
["id"]=>
int(3)
["pid"]=>
int(1)
["n"]=>
string(9) "邯郸市"
["items"]=>
array(1) {
[0]=>
array(4) {
["id"]=>
int(8)
["pid"]=>
int(3)
["n"]=>
string(9) "永年区"
["items"]=>
array(1) {
[0]=>
array(3) {
["id"]=>
int(10)
["pid"]=>
int(8)
["n"]=>
string(12) "永年区镇"
}
}
}
}
}
[1]=>
array(3) {
["id"]=>
int(9)
["pid"]=>
int(1)
["n"]=>
string(9) "武安市"
}
}
}
[1]=>
array(4) {
["id"]=>
int(2)
["pid"]=>
int(0)
["n"]=>
string(9) "北京市"
["items"]=>
array(2) {
[0]=>
array(4) {
["id"]=>
int(4)
["pid"]=>
int(2)
["n"]=>
string(9) "朝阳区"
["items"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
int(6)
["pid"]=>
int(4)
["n"]=>
string(6) "望京"
}
[1]=>
array(3) {
["id"]=>
int(7)
["pid"]=>
int(4)
["n"]=>
string(9) "酒仙桥"
}
}
}
[1]=>
array(3) {
["id"]=>
int(5)
["pid"]=>
int(2)
["n"]=>
string(9) "通州区"
}
}
}
}
根据子类id查找出所有父级分类信息
/**根据指定id 的查询,所有的父节点
* @parem $id_pid 要查询的id 或者 要查询id的pid;如果传入的是id 包括当前id 值,如果传入id_pid不包括当前id的值
* @parem $array 查分类的数据,在项目使用中此参数可以不传,直接使用sql 查询
* @parem $level 当前id所在层级,默认2
* */
function getParent($id_pid,$array=array(), $level = 2)
{
$f_name=__FUNCTION__; // 定义当前函数名
static $list=array();
//$array=Db::table('table_name')->where('id',$id_pid)->select(); TP5
foreach($array as $k=>$v)
{
if($v['id']== $id_pid)
{ //父级分类id等于所查找的id
$flg = str_repeat('|--',$level);
// 更新 名称值
$v['n'] = $flg.$v['n'];
// 输出 名称
echo $v['n']."<br/>";
$list[]=$v;
// 删除数组
unset($array[$k]);
if($v['pid']>=0)
{
$f_name($v['pid'],$array,$level-1);
}
}
}
return $list;
}
// 调用
getParent(10,$array, $level = 3);
echo "<hr/>";
getParent(8,$array, $level = 3);
调用结果显示
getParent(10,$array, $level = 3);
|--|--|--永年区镇
|--|--永年区
|--邯郸市
-----------------------------------------
getParent(8,$array, $level = 3);
河北省
|--|--|--永年区
|--|--邯郸市
|--河北省
根据父id获得所有下级子类数
/**根据指定id 查询,所有的子节
* @parem $id 要查询的id
* @parem $array 查分类的数据,在项目使用中此参数可以不传,直接使用sql 查询
* @parem $level 层级,默认1
* */
function getSon($id,$array=array(),$level=1)
{
$f_name=__FUNCTION__; // 定义当前函数名
static $list;
//$array=Db::table('table_name')->where('pid',$id)->select(); TP5
foreach ($array as $k => $v)
{
if($v['pid'] == $id)
{
$flg = str_repeat('|--',$level);
// 更新 名称值
$v['n'] = $flg.$v['n'];
// 输出 名称
echo $v['n']."<br/>";
//存放数组中
$list[] = $v;
// 删除查询过的数组
unset($array[$k]);
$f_name($v['id'],$array,$level+1);
}
}
return $list;
}
// 调用
$list=$f_name(1,$array);
调用结果:
|--邯郸市
|--|--永年区
|--|--|--永年区镇
|--武安市
php 实现无限极分类的更多相关文章
- php无限极分类以及递归(thinkphp)
php无限极分类: 无限极分类重点在于表的设计: 1在model中: class CatModel extends Model{ protected $cat = array(); public fu ...
- js实现无限极分类
转载注明出处!!! 转载注明出处!!! 转载注明出处!!! 因为要实现部门通讯录,后台传来的数据是直接从数据库里拿的部门表,所以没有层级分类,只有parentId表示从属关系,所以分类的事情就交给我来 ...
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制
在上一篇文章中我用递归方法实现了管理菜单,在上一节我也提到要考虑用缓存,也算是学习一下.Net Core的缓存机制. 关于.Net Core的缓存,官方有三种实现: 1.In Memory Cachi ...
- PHP无限极分类
当你学习php无限极分类的时候,大家都觉得一个字“难”我也觉得很难,所以,现在都还在看,因为工作要用到,所以,就必须得研究研究. 到网上一搜php无限极分类,很多,但好多都是一个,并且,写的很乱, ...
- PHP无限极分类,多种方法|很简单,这里说的很详细,其它地方说的很不好懂
当你学习php无限极分类的时候,大家都觉得一个字"难"我也觉得很难,所以,现在都还在看,因为工作要用到,所以,就必须得研究研究. 到网上一搜php无限极分类,很多,但好多都是一 ...
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现
今天做一个管理后台菜单,想着要用无限极分类,记得园子里还是什么地方见过这种写法,可今天找了半天也没找到,没办法静下心来自己写了: 首先创建节点类(我给它取名:AdminUserTree): /// & ...
- 谈一次php无限极分类的案例
作者:白狼 出处:http://www.manks.top/php_tree_deep.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追 ...
- PHP无限极分类生成树方法,无限分级
你还在用浪费时间又浪费内存的递归遍历无限极分类吗,看了该篇文章,我觉得你应该换换了.这是我在OSChina上看到的一段非常精简的PHP无限极分类生成树方法,巧在引用,整理分享了. function g ...
- php之无限极分类
首先建立分类信息表: CREATE TABLE IF NOT EXISTS `category` ( `categoryId` smallint(5) unsigned NOT NULL AUTO_I ...
- PHP无限极分类实现
简单版的PHP生成无限极分类代码.其中包括了数据库设计.以及输出分类HTML代码. SQL代码 CREATE TABLE `district` ( `id` int(10) unsigned NOT ...
随机推荐
- realsense and Mask_RCNN
###################librealsense and Mask_RCNN cd RealSennse/librealsense2018091501/librealsense/wrap ...
- 关于前端XSS攻击、短信轰炸等问题
关于前端的XSS攻击: 这里有一篇Ryf老师的写的关于使用 Content Security Policy (简称 CSP 防御)来防御xss攻击,简单来说就是设置白名单,告诉浏览器哪些链接.内容是 ...
- jQuery--加一行减一行
效果: 知识点: 克隆--clone() 追加--append() 移除--remove() 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2 ...
- 15.select into
select into SELECT INTO 语句从一个表中选取数据,然后把数据插入另一个表中. SELECT INTO 语句常用于创建表的备份复件或者用于对记录进行存档. CREATE TABLE ...
- Sqlserver中的几把锁和.net中的事务级别
当数据表被事务锁定后,我们再进行select查询时,需要为with(锁选项)来查询信息,如果不加,select将会被阻塞,直到锁被释放,下面介绍几种SQL的锁选项 SQL的几把锁 NOLOCK(不加锁 ...
- css总结12:CSS Float(浮动)
1 定义:CSS 的 Float(浮动),会使元素向左或向右移动,其周围的元素也会重新排列. 2 解释:浮动的元素,浮在界面上,脱离了HTML文本流. 元素的水平方向浮动,意味着元素只能左右移动而不能 ...
- HDU 6047 Maximum Sequence (贪心+单调队列)
题意:给定一个序列,让你构造出一个序列,满足条件,且最大.条件是 选取一个ai <= max{a[b[j], j]-j} 析:贪心,贪心策略就是先尽量产生大的,所以就是对于B序列尽量从头开始,由 ...
- eWebEditor9.x整合教程-Xproer.WordPaster
版权所有 2009-2017 荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webplug/wordpa ...
- OkHttp3的简单使用(一)
一.导入 1)gradle方式: compile 'com.squareup.okhttp3:okhttp:3.8.0'(okhttp 最新版) compile 'com.squareup.okio: ...
- [转] MySQL索引原理
MySQL索引原理 B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引.B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉 ...