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 ...
随机推荐
- 【bzoj2705】[SDOI2012]Longge的问题
2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 2507 Solved: 1531[Submit][ ...
- 张超超OC基础回顾03_结构体类型作为成员变量的特殊用法
直接上例子: 要求: 合理的设计一个”学生“类 学生有* 姓名* 生日两个属性和说出自己姓名生日方法 要求利用设计的学生类创建学生对象,并说出自己的姓名和年龄 描述学生类 事物名称: 学生(Stud ...
- 在Ubuntu安装Tomcat7.0及开机自动运行
在Ubuntu安装Tomcat7.0及开机自动运行 1.安装装Tomcat7.0 一般都是绿色版的,下载一个tomcat7.0解开到指定的目录上即可 然后进入tomcat目录的bin文件夹,执行 su ...
- How to install Freemind 1.0.1 to Ubuntu 14
安装了Freemind0.9后发现不能打开windows的1.0.1保存的*.mm文件,便对版本开始升级. 1. 从http://freemind.sourceforge.net/wiki/index ...
- 932F Escape Through Leaf
传送门 题目大意 https://www.luogu.org/problemnew/show/CF932F 分析 我们可以从叶子向根每次插入b和ans 所以我们不难发现就是相当于插入线段 于是李超树+ ...
- iPhone的home键进果汁了,按起来粘粘的感觉
解决办法是按住home键转动一下,再用棉签蘸点水或者酒精都行(注意:水不要太多,不能让水渗进去),用棉签按压home 键多转几圈就好了.
- UIView 和 CALayer区别 为啥有UIView还要CALayer?
今天,被坑了,面试的时候没回答出来,特此记录一下 一.继承结构 1: UIView的继承结构为: UIResponder : NSObject UIResponder是用来响应事件的,也就是UIVie ...
- python2.7响应数据中unicode转中文
print ("响应结果:%s" % r.content.decode('unicode_escape')) 一. 在爬虫抓取网页信息时常需要将类似"\u4eba\u75 ...
- python的requests库怎么发送带cookies的请求
背景: 在用robot做接口自动化时,有一个查询接口需要用到登录后返回的token等信息作为cookies作为参数一起请求(token是在返回体中,并不在cookies中), 刚好create se ...
- C# winform使用cefsharp
注意事项写在开头: 一)cef要求.Net FrameWork框架最少为4.5.2,所以咱们在创建工程的时候注意 二)cef不支持anycpu平台 第一步: 新建工程 第二步 添加cef nuget ...