原始数据

  1. $array = array(
  2. array('id' => 1, 'pid' => 0, 'n' => '河北省'),
  3. array('id' => 2, 'pid' => 0, 'n' => '北京市'),
  4. array('id' => 3, 'pid' => 1, 'n' => '邯郸市'),
  5. array('id' => 4, 'pid' => 2, 'n' => '朝阳区'),
  6. array('id' => 5, 'pid' => 2, 'n' => '通州区'),
  7. array('id' => 6, 'pid' => 4, 'n' => '望京'),
  8. array('id' => 7, 'pid' => 4, 'n' => '酒仙桥'),
  9. array('id' => 8, 'pid' => 3, 'n' => '永年区'),
  10. array('id' => 9, 'pid' => 1, 'n' => '武安市'),
  11. array('id' => 10, 'pid' => 8, 'n' => '永年区镇'),
  12. array('id' => 11, 'pid' => 0, 'n' => '上海市')
  13. );

生成无限极分类

  1. /** 所有的分类
  2. * @parem $array 数组
  3. * @parem $pid ,最高级别,默认为0,输出从pid 级别的数据
  4. * @parem $level 层级,默认0
  5. * */
  6. function getTree($array, $pid =0, $level = 0){
  7.  
  8. $f_name=__FUNCTION__; // 定义当前函数名
  9.  
  10. //声明静态数组,避免递归调用时,多次声明导致数组覆盖
  11. static $list = [];
  12.  
  13. foreach ($array as $key => $value){
  14. //第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点
  15. if ($value['pid'] == $pid){
  16. //父节点为根节点的节点,级别为0,也就是第一级
  17. $flg = str_repeat('|--',$level);
  18. // 更新 名称值
  19. $value['n'] = $flg.$value['n'];
  20. // 输出 名称
  21. echo $value['n']."<br/>";
  22. //把数组放到list中
  23. $list[] = $value;
  24. //把这个节点从数组中移除,减少后续递归消耗
  25. unset($array[$key]);
  26. //开始递归,查找父ID为该节点ID的节点,级别则为原级别+1
  27. $f_name($array, $value['id'], $level+1);
  28. }
  29. }
  30. return $list;
  31. }
  32. // 调用
  33. $list=getTree($array);

调用结果:

  1. 河北省
  2. |--邯郸市
  3. |--|--永年区
  4. |--|--|--永年区镇
  5. |--武安市
  6. 北京市
  7. |--朝阳区
  8. |--|--望京
  9. |--|--酒仙桥
  10. |--通州区

嵌套标签,前端可以(通过选取子节点)全选、取消全选

  1. function getTree($array, $pid =0, $level = 0){
  2.  
  3. $f_name=__FUNCTION__; // 定义当前函数名
  4.  
  5. // 空数组 不在执行
  6. if(empty($array))
  7. return;
  8.  
  9. //声明静态数组,避免递归调用时,多次声明导致数组覆盖
  10. static $html;
  11. $html.="<ul>";
  12.  
  13. foreach ($array as $key => $value){
  14.  
  15. //第一次遍历,找到父节点为根节点的节点 也就是pid=0的节点
  16. if ($value['pid'] == $pid){
  17. //父节点为根节点的节点,级别为0,也就是第一级
  18. $flg = str_repeat('|--',$level);
  19. // 更新 名称值
  20. $value['n'] = $flg.$value['n'];
  21. $html.=$temp="<li><input type=\"checkbox\" name=\"limit_id[]\" value='".$value['id']."' >".$value['n'];
  22.  
  23. //把这个节点从数组中移除,减少后续递归消耗
  24. unset($array[$key]);
  25. //开始递归,查找父ID为该节点ID的节点,级别则为原级别+1
  26. $vv=$f_name($array, $value['id'], $level+1);
  27.  
  28. // 如果顶级分类下没有一个下级,删除此分类,此步骤可以省略
  29. if(empty($vv) && ($pid<1))
  30. {
  31. $html=str_replace($temp,'',$html);
  32. }
  33. $html.="</li>\r\n";
  34.  
  35. }
  36. }
  37. $html.="</ul>\r\n";
  38.  
  39. // 删除多余的 ul 标签
  40. $html=str_replace("<ul></ul>",'',$html);
  41. return $html;
  42. }

html 输出结果

  1. <ul>
  2. <li><input type="checkbox" name="limit_id[]" value='1'>河北省
  3. <ul>
  4. <li><input type="checkbox" name="limit_id[]" value='3'>|--邯郸市
  5. <ul>
  6. <li><input type="checkbox" name="limit_id[]" value='8'>|--|--永年区
  7. <ul>
  8. <li><input type="checkbox" name="limit_id[]" value='10'>|--|--|--永年区镇
  9. </li>
  10. </ul>
  11. </li>
  12. </ul>
  13. </li>
  14. <li><input type="checkbox" name="limit_id[]" value='9'>|--武安市
  15. </li>
  16. </ul>
  17. </li>
  18. <li><input type="checkbox" name="limit_id[]" value='2'>北京市
  19. <ul>
  20. <li><input type="checkbox" name="limit_id[]" value='4'>|--朝阳区
  21. <ul>
  22. <li><input type="checkbox" name="limit_id[]" value='6'>|--|--望京
  23. </li>
  24. <li><input type="checkbox" name="limit_id[]" value='7'>|--|--酒仙桥
  25. </li>
  26. </ul>
  27. </li>
  28. <li><input type="checkbox" name="limit_id[]" value='5'>|--通州区
  29. </li>
  30. </ul>
  31. </li>
  32. </li>
  33. </ul>

jquery 操作全选

  1. //父级选中 自动选中子级,同时选中自己的父级
  2. $('input[type="checkbox"]').change(function(e) {
  3. var checked = $(this).prop("checked"),
  4. container = $(this).parent(),
  5. siblings = container.siblings();
  6.  
  7. container.find('input[type="checkbox"]').prop({
  8. indeterminate: false,
  9. checked: checked
  10. });
  11.  
  12. function checkSiblings(el) {
  13.  
  14. var parent = el.parent().parent(),
  15. all = true;
  16.  
  17. el.siblings().each(function() {
  18. return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked);
  19. });
  20.  
  21. if (all && checked) {
  22.  
  23. parent.children('input[type="checkbox"]').prop({
  24. indeterminate: false,
  25. checked: checked
  26. });
  27.  
  28. checkSiblings(parent);
  29.  
  30. } else if (all && !checked) {
  31.  
  32. parent.children('input[type="checkbox"]').prop("checked", checked);
  33. parent.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0));
  34. checkSiblings(parent);
  35.  
  36. } else {
  37.  
  38. el.parents("li").children('input[type="checkbox"]').prop({
  39. indeterminate: true,
  40. checked: false
  41. });
  42.  
  43. }
  44.  
  45. }
  46. checkSiblings(container);
  47. });
  48. // 父级选中 自动选中子级
  49. /*$("input[type=checkbox]").each(function (i,ele){
  50. let _this=$(this);
  51. _this.click(function(){
  52. if(_this.prop('checked')==true)
  53. {
  54. _this.parent().find('ul input').prop('checked',true);
  55. }else
  56. {
  57. _this.parent().find('ul input').prop('checked',false);
  58. }
  59. });
  60. });*/

数组嵌套

引用嵌套,php变量默认的传值方式是按指传递,也就是说 假如说 遍历顺序是 河北省 邯郸市 当遍历到河北省时需要把河北省放到tree中,遍历到邯郸市时,需要把邯郸市放到河北省的子节点数组中,所以这里用到了引用传递,当你对河北省做更改时,tree数组中的河北省也一并做了更改

  1. function getTree($list, $pid = 0)
  2. {
  3. $tree = [];
  4. if (!empty($list)) {
  5. $newList = [];
  6.  
  7. foreach ($list as $k => $v) {
  8. $newList[$v['id']] = $v;
  9. }
  10. foreach ($newList as $value ) {
  11. if ($pid == $value['pid']) {
  12. $tree[] = &$newList[$value['id']];
  13. } elseif (isset($newList[$value['pid']]))
  14. {
  15. $newList[$value['pid']]['items'][] = &$newList[$value['id']];
  16. }
  17. }
  18. // 如果顶级分类下没有一个下级,删除此分类,此步骤可以省略
  19. foreach ($tree as $k=>$v)
  20. {
  21. if(!isset($v['items']) && ($pid<1))
  22. unset($tree[$k]);
  23. }
  24. }
  25. return $tree;
  26. }
  27. // 调用
  28. $list=getTree($array);
  29. var_dump($list);

显示结果

  1. array(2) {
  2. [0]=>
  3. array(4) {
  4. ["id"]=>
  5. int(1)
  6. ["pid"]=>
  7. int(0)
  8. ["n"]=>
  9. string(9) "河北省"
  10. ["items"]=>
  11. array(2) {
  12. [0]=>
  13. array(4) {
  14. ["id"]=>
  15. int(3)
  16. ["pid"]=>
  17. int(1)
  18. ["n"]=>
  19. string(9) "邯郸市"
  20. ["items"]=>
  21. array(1) {
  22. [0]=>
  23. array(4) {
  24. ["id"]=>
  25. int(8)
  26. ["pid"]=>
  27. int(3)
  28. ["n"]=>
  29. string(9) "永年区"
  30. ["items"]=>
  31. array(1) {
  32. [0]=>
  33. array(3) {
  34. ["id"]=>
  35. int(10)
  36. ["pid"]=>
  37. int(8)
  38. ["n"]=>
  39. string(12) "永年区镇"
  40. }
  41. }
  42. }
  43. }
  44. }
  45. [1]=>
  46. array(3) {
  47. ["id"]=>
  48. int(9)
  49. ["pid"]=>
  50. int(1)
  51. ["n"]=>
  52. string(9) "武安市"
  53. }
  54. }
  55. }
  56. [1]=>
  57. array(4) {
  58. ["id"]=>
  59. int(2)
  60. ["pid"]=>
  61. int(0)
  62. ["n"]=>
  63. string(9) "北京市"
  64. ["items"]=>
  65. array(2) {
  66. [0]=>
  67. array(4) {
  68. ["id"]=>
  69. int(4)
  70. ["pid"]=>
  71. int(2)
  72. ["n"]=>
  73. string(9) "朝阳区"
  74. ["items"]=>
  75. array(2) {
  76. [0]=>
  77. array(3) {
  78. ["id"]=>
  79. int(6)
  80. ["pid"]=>
  81. int(4)
  82. ["n"]=>
  83. string(6) "望京"
  84. }
  85. [1]=>
  86. array(3) {
  87. ["id"]=>
  88. int(7)
  89. ["pid"]=>
  90. int(4)
  91. ["n"]=>
  92. string(9) "酒仙桥"
  93. }
  94. }
  95. }
  96. [1]=>
  97. array(3) {
  98. ["id"]=>
  99. int(5)
  100. ["pid"]=>
  101. int(2)
  102. ["n"]=>
  103. string(9) "通州区"
  104. }
  105. }
  106. }
  107. }

根据子类id查找出所有父级分类信息

  1. /**根据指定id 的查询,所有的父节点
  2. * @parem $id_pid 要查询的id 或者 要查询id的pid;如果传入的是id 包括当前id 值,如果传入id_pid不包括当前id的值
  3. * @parem $array 查分类的数据,在项目使用中此参数可以不传,直接使用sql 查询
  4. * @parem $level 当前id所在层级,默认2
  5. * */
  6. function getParent($id_pid,$array=array(), $level = 2)
  7. {
  8. $f_name=__FUNCTION__; // 定义当前函数名
  9. static $list=array();
  10. //$array=Db::table('table_name')->where('id',$id_pid)->select(); TP5
  11. foreach($array as $k=>$v)
  12. {
  13. if($v['id']== $id_pid)
  14. { //父级分类id等于所查找的id
  15. $flg = str_repeat('|--',$level);
  16. // 更新 名称值
  17. $v['n'] = $flg.$v['n'];
  18. // 输出 名称
  19. echo $v['n']."<br/>";
  20. $list[]=$v;
           // 删除数组
           unset($array[$k]);
  21. if($v['pid']>=0)
  22. {
  23. $f_name($v['pid'],$array,$level-1);
  24. }
  25. }
  26. }
  27. return $list;
  28. }
  29. // 调用
  30. getParent(10,$array, $level = 3);
  31. echo "<hr/>";
  32. getParent(8,$array, $level = 3);

调用结果显示

  1. getParent(10,$array, $level = 3);
  2. |--|--|--永年区镇
  3. |--|--永年区
  4. |--邯郸市
  5. -----------------------------------------
  6. getParent(8,$array, $level = 3);
  7. 河北省
  8. |--|--|--永年区
  9. |--|--邯郸市
  10. |--河北省

根据父id获得所有下级子类数

  1. /**根据指定id 查询,所有的子节 
    * @parem $id 要查询的id 
    * @parem $array 查分类的数据,在项目使用中此参数可以不传,直接使用sql 查询

    * @parem $level 层级,默认1
  2. * */
  3. function getSon($id,$array=array(),$level=1)
  4. {
  5. $f_name=__FUNCTION__; // 定义当前函数名
  6. static $list;
  7. //$array=Db::table('table_name')->where('pid',$id)->select(); TP5
  8. foreach ($array as $k => $v)
  9. {
  10. if($v['pid'] == $id)
  11. {
  12. $flg = str_repeat('|--',$level);
  13. // 更新 名称值
  14. $v['n'] = $flg.$v['n'];
  15. // 输出 名称
  16. echo $v['n']."<br/>";
  17. //存放数组中
  18. $list[] = $v;
           // 删除查询过的数组
            unset($array[$k]);
  19. $f_name($v['id'],$array,$level+1);
  20. }
  21. }
  22. return $list;
  23. }
    // 调用
  24. $list=$f_name(1,$array);

调用结果:

  1. |--邯郸市
  2. |--|--永年区
  3. |--|--|--永年区镇
  4. |--武安市

php 实现无限极分类的更多相关文章

  1. php无限极分类以及递归(thinkphp)

    php无限极分类: 无限极分类重点在于表的设计: 1在model中: class CatModel extends Model{ protected $cat = array(); public fu ...

  2. js实现无限极分类

    转载注明出处!!! 转载注明出处!!! 转载注明出处!!! 因为要实现部门通讯录,后台传来的数据是直接从数据库里拿的部门表,所以没有层级分类,只有parentId表示从属关系,所以分类的事情就交给我来 ...

  3. C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制

    在上一篇文章中我用递归方法实现了管理菜单,在上一节我也提到要考虑用缓存,也算是学习一下.Net Core的缓存机制. 关于.Net Core的缓存,官方有三种实现: 1.In Memory Cachi ...

  4. PHP无限极分类

      当你学习php无限极分类的时候,大家都觉得一个字“难”我也觉得很难,所以,现在都还在看,因为工作要用到,所以,就必须得研究研究. 到网上一搜php无限极分类,很多,但好多都是一个,并且,写的很乱, ...

  5. PHP无限极分类,多种方法|很简单,这里说的很详细,其它地方说的很不好懂

    当你学习php无限极分类的时候,大家都觉得一个字"难"我也觉得很难,所以,现在都还在看,因为工作要用到,所以,就必须得研究研究.   到网上一搜php无限极分类,很多,但好多都是一 ...

  6. C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现

    今天做一个管理后台菜单,想着要用无限极分类,记得园子里还是什么地方见过这种写法,可今天找了半天也没找到,没办法静下心来自己写了: 首先创建节点类(我给它取名:AdminUserTree): /// & ...

  7. 谈一次php无限极分类的案例

    作者:白狼 出处:http://www.manks.top/php_tree_deep.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追 ...

  8. PHP无限极分类生成树方法,无限分级

    你还在用浪费时间又浪费内存的递归遍历无限极分类吗,看了该篇文章,我觉得你应该换换了.这是我在OSChina上看到的一段非常精简的PHP无限极分类生成树方法,巧在引用,整理分享了. function g ...

  9. php之无限极分类

    首先建立分类信息表: CREATE TABLE IF NOT EXISTS `category` ( `categoryId` smallint(5) unsigned NOT NULL AUTO_I ...

  10. PHP无限极分类实现

    简单版的PHP生成无限极分类代码.其中包括了数据库设计.以及输出分类HTML代码. SQL代码 CREATE TABLE `district` ( `id` int(10) unsigned NOT ...

随机推荐

  1. php 5.3 以上fpm安装

    安装PHP #wget http://cn2.php.net/get/php-5.3.8.tar.gz/from/cn.php.net/mirror #tar -zxvf php-5.3.8.tar. ...

  2. LoadRunner 关联和集合点、检查点

    1)关联的定义 很多时候,当时录完之后,没有问题.过一段时间再跑脚本,就不会成功.比如session,过期了,再一次使用,就会出错.这个时候,需要在每次访问的时候动态的拿到session,这种情况就需 ...

  3. struts2 框架的基本使用

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...

  4. convertTo

    转自 http://blog.csdn.net/xiaxiazls/article/details/51204265 在使用Opencv中,常常会出现读取一个图片内容后要把图片内容的像素信息转为浮点并 ...

  5. java中的监听事件

    java监听器实现的类 1.ServletContextListener:对servlet上下文的创建和销毁监听 2.ServletContextAttributeListener:监听servlet ...

  6. MagicNotes:如何迈向工作的坦途

    MagicNotes,思绪随风飞扬,不抓住写下来明天就会忘记了. 昨晚在知乎上偶尔看到 @雨农 的关于“为什么我那么努力,吃了那么多苦,也没见那么优秀?”的一个回复,心里有所触动. 本人专科毕业3-4 ...

  7. Regist&Login

    关于注册页面和登录页面的业务流程 form表单中确定action提交地址 method 确定提交的方法--->写出相对应的Servlet,假如接受的数据不多 ,那么用 String userna ...

  8. javascript总结4:javascript常见变量

    1 javascript变量 定义:变量在计算机中,是用于存储信息的"容器". 2  使用方法: 2-1 定义变量: var n1; 2-2 变量赋值: var n2=23.45; ...

  9. Java之集合框架vector类设计原理

  10. UIView的alpha、hidden和opaque属性之间的关系和区别[转]

    UIView的alpha.hidden和opaque属性之间的关系和区别 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/ ...