• 售前

  • 售后

热门帖子
入门百科

php无穷级评论嵌套实今世码

[复制链接]
123457321 显示全部楼层 发表于 2021-10-25 20:03:50 |阅读模式 打印 上一主题 下一主题
我在设计BB的过程中,也一直在思索是否可以不通过递归来实现无穷级分类的结构显现和父子结构查找,由于如果不对这里的算法进行优化结果可能是致命的!试想一下,一篇文章如果评论数为300,按正常的递归算法,至少就得查询数据库301次,而且照旧在没有任何嵌套的环境下,如果有过一两级嵌套大概评论数过1000,那数据库不是直接宕掉?
而实际上,PHP强大的数组处理处罚能力已经能资助我们快速方便的办理这个题目。下图为一个无穷级分类的
数据库结构:
IDparentID newsID commts
108文章ID为8的评论
21 8对ID为1的评论的回复
328对ID为2的评论的回复
要在前台嵌套式的显现文章编号8的评论,实在我们只用查询一次数据库,即“SELECT * FROM TABLE WHERE newsID=8”,而把后期的递归工作交给强大的PHP数组来完成。这里可能涉及的题目就是数组的结构关系的重组,即将所有停顿在一级分类上的评论全部放到自己的parentID下,形成children项。
下面将BBComment类中这块的代码粘贴出来,希望与大家分享下我的思路,也希望大家可以或许提出更好更有用率的算法。
方法一
  1. /**
  2. * 按ID条件从评论数组中递归查找
  3. *
  4. */
  5. function getCommentsFromAryById($commtAry, $id)
  6. {
  7. if ( !is_array($commtAry) ) return FALSE;
  8. foreach($commtAry as $key=>$value) {
  9.   if ( $value['id'] == $id ) return $value;
  10.   if ( isset($value['children']) && is_array($children) ) $this->getCommentsFormAryById($value['children'], $id);
  11. }
  12. }
  13. /**
  14. * 追加 子评论 到 主评论 中,并形成children子项
  15. *
  16. * @param array $commtAry 原评论数据引用
  17. * @param int $parentId 主评论ID
  18. * @param array $childrenAry 子评论的值
  19. */
  20. function addChildenToCommentsAry($commtAry, $parentId, $childrenAry)
  21. {
  22. if ( !is_array($commtAry) ) return FALSE;
  23. foreach($commtAry as $key=>$value) {
  24.   if ( $value['id'] == $parentId ) {
  25.    $commtAry[$key]['children'][] = $childrenAry;
  26.    return TRUE;
  27.   }
  28.   if ( isset($value['children']) ) $this->addChildenToCommentsAry($commtAry[$key]['children'], $parentId, $childrenAry);
  29. }
  30. }
  31. $result = $this->BBDM->select($table, $column, $condition, 0, 1000);
  32. /* 开始进行嵌套评论结构重组 */
  33. array_shift($result);
  34. $count = count($result);
  35. $i  = 0;
  36. while( $i<$count ) {
  37.   if ( '0' != $result[$i]['parentId'] ) {
  38.    $this->addChildenToCommentsAry($result, $result[$i]['parentId'], $result[$i]);
  39.    unset($result[$i]);
  40.   }
  41.   $i++;
  42. }
  43. $result = array_values($result);
  44. /* 重组结束 */
复制代码
实现方法二
焦点代码摘自WordPress
  1. <?php
  2. $comments = array (
  3.   array (
  4.     'id' => '3',
  5.     'parent' => '0'
  6.   ),
  7.   array (
  8.     'id' => '9',
  9.     'parent' => '0'
  10.   ),
  11.   array (
  12.     'id' => '1',
  13.     'parent' => '3'
  14.   ),
  15.   array (
  16.     'id' => '2',
  17.     'parent' => '3'
  18.   ),
  19.   array (
  20.     'id' => '5',
  21.     'parent' => '1'
  22.   ),
  23.   array (
  24.     'id' => '7',
  25.     'parent' => '1'
  26.   )
  27. );
  28. function html5_comment($comment) {
  29.   echo '<li>';
  30.   echo 'id:', $comment['id'], ' parent:', $comment['parent'];
  31. }
  32. function start_el(& $output, $comment) {
  33.   ob_start();
  34.   html5_comment($comment);
  35.   $output .= ob_get_clean();
  36. }
  37. function end_el(& $output) {
  38.   $output .= "</li><!-- #comment-## -->\n";
  39. }
  40. function start_lvl(& $output) {
  41.   $output .= '<ol class="children">' . "\n";
  42. }
  43. function end_lvl(& $output) {
  44.   $output .= "</ol><!-- .children -->\n";
  45. }
  46. function display_element($e, & $children_elements, $max_depth, $depth, & $output) {
  47.   $id = $e['id'];
  48.   start_el($output, $e); //当前评论的开始代码
  49.   if ($max_depth > $depth +1 && isset ($children_elements[$id])) { //如果没超过最大层,并且存在子元素数组
  50.     foreach ($children_elements[$id] as $child) {
  51.       if (!isset ($newlevel)) { //第一次循环没设置变量$newlevel,所以把$newlevel设为true,并且开始子元素的开始代码;第二次及之后的循环,已经设置了$newlevel,就不会再添加子元素的开始代码。因为同一批循环时兄弟元素,所以只需要一个子元素开始代码,循环内容为并列关系。
  52.         $newlevel = true;
  53.         start_lvl($output);
  54.       }
  55.       display_element_template($child, $children_elements, $max_depth, $depth +1, $output); //$child作为参数,继续去寻找下级元素
  56.     }
  57.     unset ($children_elements[$id]); //用完释放变量,以后就不会重复判断该值了,递归后继续判断剩下的子元素
  58.   }
  59.   if (isset ($newlevel) && $newlevel) { //如果前面找到了子元素,这里就要执行子元素的结束代码
  60.     end_lvl($output);
  61.   }
  62.   end_el($output); //当前评论的结束代码
  63. }
  64. function display_element_template($e, & $children_elements, $max_depth, $depth, & $output) {
  65.   $id = $e['id'];
  66.   display_element($e, $children_elements, $max_depth, $depth, $output);
  67.   if ($max_depth <= $depth +1 && isset ($children_elements[$id])) { //如果超出最大层级,并且子元素存在的话,以$child为参数继续往下找
  68.     foreach ($children_elements[$id] as $child) {
  69.       display_element_template($child, $children_elements, $max_depth, $depth, $output);
  70.     }
  71.     unset ($children_elements[$id]); //用完释放变量
  72.   }
  73. }
  74. function comments_list($comments) {
  75.   $top_level_elements = array ();
  76.   $children_elements = array ();
  77.   foreach ($comments as $e) {
  78.     if (0 == $e['parent']) {
  79.       $top_level_elements[] = $e;
  80.     } else {
  81.       $children_elements[$e['parent']][] = $e;
  82.     }
  83.   }
  84.   $output = '';
  85.   foreach ($top_level_elements as $e) {
  86.     display_element_template($e, $children_elements, 2, 0, $output);
  87.   }
  88.   //var_dump($children_elements);//由于每次用完$children_elements后都会释放变量,所以到最后$children_elements为空数组
  89.   return $output;
  90. }
  91. echo '<ol class="comment-list">', comments_list($comments), '</ol>';
复制代码
这篇文章就先容到这了,实在大家多参考一些开源的cms也可以看到许多不错的代码,希望大家以后多多支持脚本之家

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作