广州传奇网络

地址:广州市天河区东圃大马路富华楼C座

电话:13808825895

邮箱:gz020wbs@163.com

QQ:1564443073

网址:http://www.020wbs.com/

首页 > 二次开发Ecshop二次开发 > ecshop无限级分类

二次开发Ecshop二次开发

二次开发Ecshop二次开发

ecshop无限级分类

研究了一下ecshop的无限级商品分类,发现网上并没有人给出对此功能函数解析,于是为了便于大家更好的理解此函数的算法我写了解析,不足之处与大家交流.
color=Red]此函数采用树的非递归前序遍历进行树的构造
详细见我的blog:ecshop的无限级商品分类详解

  1. [php]function cat_options($spec_cat_id$arr
  2.     static $cat_options = array(); 
  3.     if (isset($cat_options[$spec_cat_id])) 
  4.     { 
  5.         return $cat_options[$spec_cat_id]; 
  6.     } 
  7.     if (!isset($cat_options[0])) 
  8.     { 
  9.        /* 
  10.         初始化关键参数: 
  11.         $level:当前子节点深度 
  12.         $last_cat_id:当前父节点ID 
  13.         $options:带有缩进级别的数组 
  14.         $cat_id_array:沿同一路径的父节点依次进驻 
  15.         $level_array:该节点的子节点深度,也是依次进驻 
  16.        */[/php] 

ecshop无限级分类的解析,认真分析后发现真的其算法还是比较精典的其实并不难理解我有举例方便大家理解

  1. [php] 
  2. function cat_options($spec_cat_id$arr
  3. static $cat_options = array(); 
  4. if (isset($cat_options[$spec_cat_id])) 
  5. return $cat_options[$spec_cat_id]; 
  6. /* 
  7. 初始化关键参数: 
  8. $level:当前子节点深度 
  9. $last_cat_id:当前父节点ID 
  10. $options:带有缩进级别的数组 
  11. $cat_id_array:沿同一路径的父节点依次进驻 
  12. $level_array:该节点的子节点深度,也是依次进驻 
  13. */ 
  14. if (!isset($cat_options[0])) 
  15. $level = $last_cat_id = 0; 
  16. $options = $cat_id_array = $level_array = array(); 
  17. while (!emptyempty($arr))//如果还有待构造的节点则继续遍历 
  18. {  
  19. foreach ($arr AS $key => $value
  20. {  
  21. $cat_id = $value['cat_id']; 
  22. //一级分类结点 
  23. if ($level == 0 && $last_cat_id == 0) 
  24. {  
  25. if ($value['parent_id'] > 0) 
  26. break
  27. $options[$cat_id] = $value
  28. $options[$cat_id]['level'] = $level
  29. $options[$cat_id]['id'] = $cat_id
  30. $options[$cat_id]['name'] = $value['cat_name']; 
  31. //遍历过了就不再遍历 
  32. unset($arr[$key]); 
  33. if ($value['has_children'] == 0) 
  34. continue
  35. $last_cat_id = $cat_id;//下层结点的父亲结点 
  36. $cat_id_array = array($cat_id); 
  37. $level_array[$last_cat_id] = ++$level
  38. continue
  39. //当前结点的父亲结点ID等于它的上一级结点ID 
  40. if ($value['parent_id'] == $last_cat_id
  41. {  
  42. $options[$cat_id] = $value
  43. $options[$cat_id]['level'] = $level
  44. $options[$cat_id]['id'] = $cat_id
  45. $options[$cat_id]['name'] = $value['cat_name']; 
  46. unset($arr[$key]);//遍历过了就不再遍历 
  47. //如果当前结点有孩子则当前结点要进驻,但不再遍历;反之不进驻也不再遍历 
  48. if ($value['has_children'] > 0) 
  49. if (end($cat_id_array) != $last_cat_id
  50. $cat_id_array[] = $last_cat_id
  51. $last_cat_id = $cat_id;//当现结点做为下一级结点的新的父亲结点 
  52. $cat_id_array[] = $cat_id;//进驻 
  53.  
  54. $level_array[$last_cat_id] = ++$level;//当前结点的下一级结点深度 
  55.  
  56. elseif ($value['parent_id'] > $last_cat_id
  57. {//如果当前结点父亲深度大于目前父亲结点的深度则进行下一轮循环 
  58. break
  59. }//endforeach 
  60. $count = count($cat_id_array); 
  61. if ($count > 1) 
  62. //取出最后进驻的父亲节点作为当前父亲节点 
  63. $last_cat_id = array_pop($cat_id_array); 
  64. elseif ($count == 1) 
  65. if ($last_cat_id != end($cat_id_array)) 
  66. //进驻的父亲结点只有一个时并且没有作为当前父亲节点时把它取出 
  67. $last_cat_id = end($cat_id_array); 
  68. else 
  69. //否则最后取出的父亲结点一定是一级分类结点 
  70. $level = 0; 
  71. $last_cat_id = 0; 
  72. $cat_id_array = array(); 
  73. continue
  74.  
  75. if ($last_cat_id && isset($level_array[$last_cat_id])) 
  76. {  
  77. //取出当前结点的深度 
  78. $level = $level_array[$last_cat_id]; 
  79. else 
  80. {  
  81. $level = 0; 
  82. }//end while,此时已完成非递归前序遍历构造树的工作,其中$options已保存了从根结点开始的所有结点带有分层性质的数组 
  83. $cat_options[0] = $options
  84. else 
  85. $options = $cat_options[0]; 
  86. //如果从0开始即取整个树则直接返回不再处理. 
  87. if (!$spec_cat_id
  88. return $options
  89. //否则开始从指定结点截取,以下比较简单我还是稍微说说吧,要说就说几个参数含义吧 
  90. /* 
  91. $spec_cat_id_level:截取结点的深度 
  92. $spec_cat_id_array:最终返回的以该结点为根结点的一棵商品分类树 
  93. 最终返回的数组是这样排序的:按父亲结点大小,按直接父亲结点,按同一父亲结点这样的先根遍历,具个例子: 
  94. 一级结点有1,5 二级结点有2,6,7 三级结点有8,9,如果1的直接孩子是2,6而2的直接孩子是8,9;另外 
  95. 5的直接孩子是7那么最终的数组是这样排列的1->2->8->9->6->5->7  
  96. */ 
  97. else 
  98. if (emptyempty($options[$spec_cat_id])) 
  99. return array(); 
  100. $spec_cat_id_level = $options[$spec_cat_id]['level']; 
  101.  
  102. foreach ($options AS $key => $value
  103. if ($key != $spec_cat_id
  104. unset($options[$key]); 
  105. else 
  106. break
  107. $spec_cat_id_array = array(); 
  108. foreach ($options AS $key => $value
  109. if (($spec_cat_id_level == $value['level'] && $value['cat_id'] != $spec_cat_id) || 
  110. ($spec_cat_id_level > $value['level'])) 
  111. break
  112. else 
  113. $spec_cat_id_array[$key] = $value
  114. $cat_options[$spec_cat_id] = $spec_cat_id_array
  115. return $spec_cat_id_array
  116. [/php]