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 ...
随机推荐
- Ant之build.xml详解---可用
Ant的概念 :在Eclipse中使用Ant Ant是Java平台下非常棒的批处理命令执行程序,能非常方便地自动完成编译,测试,打包,部署等等一系列任务,大大提高开发效率. Ant和make命令很像. ...
- mfs测试
续1 6. 参考文献: 6.1 文献 http://sery.blog.51cto.com/10037/263515 田逸 http://bbs.chinaunix.net/thread-16438 ...
- jquery 获取url 参数方法 以及 解决url中文问题
//jQuery 动态给a 标签赋值 跳转 新的页面打开. /* <a class="btn btn-success" id="test" target= ...
- 3-java中String值为空字符串与null的判断方法
java中String值为空字符串与null的判断方法 2018年01月21日 14:53:45 阅读数:1189 Java空字符串与null的区别 1.类型 null表示的是一个对象的值,而不是一个 ...
- RabbitMQ(pika模块)
RabbitMQ 基础 2 3 4 5 6 7 8 安装配置epel源 $ rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-r ...
- Luogu 1099 树网的核
bzoj1999 数据加强版(n <= 5e5) 较早的noip题,值得研究 重要结论:直径的最长性,任何从直径中离开直径的点到它离开的点的距离,都不会比直径的另一端到它离开的点长(否则就有新的 ...
- SQLAlchemy 进阶
SQLAlchemy使用 1.执行原生SQL语句 from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engin ...
- java - Logback获取方法名称
java - Logback获取方法名称 摘自: https://blog.csdn.net/qq853632587/article/details/78222780 我们目前正在从 Log4J 迁移 ...
- 通过批处理操作注册表实现winform应用中Webbrowser以指定的IE版本加载网页
通过批处理操作注册表实现winform应用中Webbrowser以指定的IE版本加载网页 rem 强制WebBrowser控件使用指定IE版本显示应用的网页 IF EXIST %windir%\Sys ...
- 防止SQL注入方法总结
一.参数化SQL 是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,用@来表示参数. 在使用参数化查询的情况下,数据库服务器不会将参数的内容视为 ...