对ecshop中的无限级分类的分析

WBOY
Libérer: 2016-07-25 09:03:26
original
731 Les gens l'ont consulté
  1. function cat_options($spec_cat_id, $arr)

  2. {
  3. static $cat_options = array();
  4. if (isset($cat_options[$spec_cat_id]))
  5. {
  6. return $cat_options[$spec_cat_id];
  7. }
  8. /*
  9. 初始化关键参数:
  10. $level:当前子节点深度
  11. $last_cat_id:当前父节点ID
  12. $options:带有缩进级别的数组
  13. $cat_id_array:沿同一路径的父节点依次进驻
  14. $level_array:该节点的子节点深度,也是依次进驻
  15. */
  16. if (!isset($cat_options[0]))
  17. {
  18. $level = $last_cat_id = 0;
  19. $options = $cat_id_array = $level_array = array();
  20. while (!empty($arr))//如果还有待构造的节点则继续遍历
  21. {
  22. foreach ($arr AS $key => $value)
  23. {
  24. $cat_id = $value['cat_id'];
  25. //一级分类结点
  26. if ($level == 0 && $last_cat_id == 0)
  27. {
  28. if ($value['parent_id'] > 0)
  29. {
  30. break;
  31. }
  32. $options[$cat_id] = $value;
  33. $options[$cat_id]['level'] = $level;
  34. $options[$cat_id]['id'] = $cat_id;
  35. $options[$cat_id]['name'] = $value['cat_name'];
  36. //遍历过了就不再遍历
  37. unset($arr[$key]);
  38. if ($value['has_children'] == 0)
  39. {
  40. continue;
  41. }
  42. $last_cat_id = $cat_id;//下层结点的父亲结点
  43. $cat_id_array = array($cat_id);
  44. $level_array[$last_cat_id] = ++$level;
  45. continue;
  46. }
  47. //当前结点的父亲结点ID等于它的上一级结点ID
  48. if ($value['parent_id'] == $last_cat_id)
  49. {
  50. $options[$cat_id] = $value;
  51. $options[$cat_id]['level'] = $level;
  52. $options[$cat_id]['id'] = $cat_id;
  53. $options[$cat_id]['name'] = $value['cat_name'];
  54. unset($arr[$key]);//遍历过了就不再遍历
  55. //如果当前结点有孩子则当前结点要进驻,但不再遍历;反之不进驻也不再遍历
  56. if ($value['has_children'] > 0)
  57. {
  58. if (end($cat_id_array) != $last_cat_id)
  59. {
  60. $cat_id_array[] = $last_cat_id;
  61. }
  62. $last_cat_id = $cat_id;//当现结点做为下一级结点的新的父亲结点
  63. $cat_id_array[] = $cat_id;//进驻
  64. $level_array[$last_cat_id] = ++$level;//当前结点的下一级结点深度

  65. }
  66. }

  67. elseif ($value['parent_id'] > $last_cat_id)
  68. {//如果当前结点父亲深度大于目前父亲结点的深度则进行下一轮循环
  69. break;
  70. }
  71. }//endforeach
  72. $count = count($cat_id_array);
  73. if ($count > 1)
  74. {
  75. //取出最后进驻的父亲节点作为当前父亲节点
  76. $last_cat_id = array_pop($cat_id_array);
  77. }
  78. elseif ($count == 1)
  79. {
  80. if ($last_cat_id != end($cat_id_array))
  81. {
  82. //进驻的父亲结点只有一个时并且没有作为当前父亲节点时把它取出
  83. $last_cat_id = end($cat_id_array);
  84. }
  85. else
  86. { //否则最后取出的父亲结点一定是一级分类结点
  87. $level = 0;
  88. $last_cat_id = 0;
  89. $cat_id_array = array();
  90. continue;
  91. }
  92. }
  93. if ($last_cat_id && isset($level_array[$last_cat_id]))

  94. {
  95. //取出当前结点的深度
  96. $level = $level_array[$last_cat_id];
  97. }
  98. else
  99. {
  100. $level = 0;
  101. }
  102. }//end while,此时已完成非递归前序遍历构造树的工作,其中$options已保存了从根结点开始的所有结点带有分层性质的数组
  103. $cat_options[0] = $options;
  104. }
  105. else
  106. {
  107. $options = $cat_options[0];
  108. }
  109. //如果从0开始即取整个树则直接返回不再处理.
  110. if (!$spec_cat_id)
  111. {
  112. return $options;
  113. }
  114. //否则开始从指定结点截取,以下比较简单我还是稍微说说吧,要说就说几个参数含义吧
  115. /*
  116. $spec_cat_id_level:截取结点的深度
  117. $spec_cat_id_array:最终返回的以该结点为根结点的一棵商品分类树
  118. 最终返回的数组是这样排序的:按父亲结点大小,按直接父亲结点,按同一父亲结点这样的先根遍历,具个例子:
  119. 一级结点有1,5 二级结点有2,6,7 三级结点有8,9,如果1的直接孩子是2,6而2的直接孩子是8,9;另外
  120. 5的直接孩子是7那么最终的数组是这样排列的1->2->8->9->6->5->7
  121. */
  122. else
  123. {
  124. if (empty($options[$spec_cat_id]))
  125. {
  126. return array();
  127. }
  128. $spec_cat_id_level = $options[$spec_cat_id]['level'];
  129. foreach ($options AS $key => $value)

  130. {
  131. if ($key != $spec_cat_id)
  132. {
  133. unset($options[$key]);
  134. }
  135. else
  136. {
  137. break;
  138. }
  139. }
  140. $spec_cat_id_array = array();
  141. foreach ($options AS $key => $value)
  142. {
  143. if (($spec_cat_id_level == $value['level'] && $value['cat_id'] != $spec_cat_id) ||
  144. ($spec_cat_id_level > $value['level']))
  145. {
  146. break;
  147. }
  148. else
  149. {
  150. $spec_cat_id_array[$key] = $value;
  151. }
  152. }
  153. $cat_options[$spec_cat_id] = $spec_cat_id_array;
  154. return $spec_cat_id_array;
  155. }
  156. }
  157. ?>
复制代码


Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal