> 백엔드 개발 > PHP 튜토리얼 > PHP 무제한 주석 중첩 구현 코드 PHP 기술

PHP 무제한 주석 중첩 구현 코드 PHP 기술

jacklove
풀어 주다: 2023-04-01 20:26:01
원래의
1881명이 탐색했습니다.

이 글은 BB를 설계하는 과정에서 재귀 없이 무한 레벨 분류와 부모-자식 구조 검색의 구조적 표시를 구현하는 것이 가능한지에 대한 PHP의 무한 레벨 주석 중첩 예제에 대한 소개입니다. , 왜냐하면 여기 알고리즘을 사용하지 않으면 최적화의 결과가 치명적일 수 있기 때문입니다

BB를 설계하는 과정에서 재귀 없이 무한한 분류 구조 표시와 부모-자식 구조 검색이 가능한지 고민을 했었는데, 여기 알고리즘이 최적화되지 않으면 그 결과는 치명적일 수 있기 때문입니다! 기사에 300개의 댓글이 있는 경우 일반 재귀 알고리즘에 따라 데이터베이스를 최소 301번 쿼리해야 하며 이는 중첩 수준이 하나 또는 두 개이거나 댓글 수가 1,000을 초과하는 경우입니다. , 그러면 데이터베이스가 직접 충돌하지 않습니까?
사실, PHP의 강력한 배열 처리 기능은 이미 이 문제를 빠르고 편리하게 해결하는 데 도움을 주고 있습니다. 아래 그림은 무한하게 분류된 데이터베이스 구조를 보여줍니다.

IDparentID newsID commts

기사 ID가 8인 댓글 108개

21 ID가 1인 댓글에 8개의 답글
ID가 2인 댓글에 328명이 답글

기사 번호 8의 댓글을 표시하려면 중첩된 방식으로 프런트엔드를 쿼리하려면 실제로 데이터베이스를 한 번만 쿼리하면 됩니다. 즉, "SELECT * FROM TABLE WHERE newsID=8"이고 이후의 재귀 작업은 강력한 PHP 배열에 맡기면 됩니다. 여기서 발생할 수 있는 문제는 배열의 구조적 관계를 재구성하는 것입니다. 즉, 첫 번째 수준 범주에 있는 모든 주석을 자체 parentID 아래에 넣어 하위 항목을 형성하는 것입니다.

이 코드를 아래 BBCComment 클래스에 붙여넣겠습니다. 제 아이디어를 여러분과 공유하고 모두가 더 좋고 효율적인 알고리즘을 생각해낼 수 있기를 바랍니다.


방법 1

/** 
 * 按ID条件从评论数组中递归查找 
 * 
 */ 
function getCommentsFromAryById($commtAry, $id) 
{ 
 if ( !is_array($commtAry) ) return FALSE; 
 foreach($commtAry as $key=>$value) { 
  if ( $value['id'] == $id ) return $value; 
  if ( isset($value['children']) && is_array($children) ) $this->getCommentsFormAryById($value['children'], $id); 
 } 
} 
/** 
 * 追加 子评论 到 主评论 中,并形成children子项 
 * 
 * @param array $commtAry 原评论数据引用 
 * @param int $parentId 主评论ID 
 * @param array $childrenAry 子评论的值 
 */ 
function addChildenToCommentsAry($commtAry, $parentId, $childrenAry) 
{ 
 if ( !is_array($commtAry) ) return FALSE; 
 
 foreach($commtAry as $key=>$value) { 
  if ( $value['id'] == $parentId ) { 
   $commtAry[$key]['children'][] = $childrenAry; 
   return TRUE; 
  } 
  if ( isset($value['children']) ) $this->addChildenToCommentsAry($commtAry[$key]['children'], $parentId, $childrenAry); 
 } 
} 
 $result = $this->BBDM->select($table, $column, $condition, 0, 1000); 
 
 /* 开始进行嵌套评论结构重组 */ 
 array_shift($result); 
 $count = count($result); 
 $i  = 0; 
 while( $i<$count ) { 
  if ( &#39;0&#39; != $result[$i][&#39;parentId&#39;] ) { 
   $this->addChildenToCommentsAry($result, $result[$i][&#39;parentId&#39;], $result[$i]); 
   unset($result[$i]); 
  } 
  $i++; 
 } 
 $result = array_values($result); 
 /* 重组结束 */
로그인 후 복사

구현 방법 2

핵심 코드는 WordPress에서 발췌

<?php
$comments = array (
  array (
    &#39;id&#39; => &#39;3&#39;,
    &#39;parent&#39; => &#39;0&#39;
  ),
  array (
    &#39;id&#39; => &#39;9&#39;,
    &#39;parent&#39; => &#39;0&#39;
  ),
  array (
    &#39;id&#39; => &#39;1&#39;,
    &#39;parent&#39; => &#39;3&#39;
  ),
  array (
    &#39;id&#39; => &#39;2&#39;,
    &#39;parent&#39; => &#39;3&#39;
  ),
  array (
    &#39;id&#39; => &#39;5&#39;,
    &#39;parent&#39; => &#39;1&#39;
  ),
  array (
    &#39;id&#39; => &#39;7&#39;,
    &#39;parent&#39; => &#39;1&#39;
  )
);
function html5_comment($comment) {
  echo &#39;<li>&#39;;
  echo &#39;id:&#39;, $comment[&#39;id&#39;], &#39; parent:&#39;, $comment[&#39;parent&#39;];
}
function start_el(& $output, $comment) {
  ob_start();
  html5_comment($comment);
  $output .= ob_get_clean();
}
function end_el(& $output) {
  $output .= "</li><!-- #comment-## -->\n";
}
function start_lvl(& $output) {
  $output .= &#39;<ol class="children">&#39; . "\n";
}
function end_lvl(& $output) {
  $output .= "</ol><!-- .children -->\n";
}
function display_element($e, & $children_elements, $max_depth, $depth, & $output) {
  $id = $e[&#39;id&#39;];
  start_el($output, $e); //当前评论的开始代码
  if ($max_depth > $depth +1 && isset ($children_elements[$id])) { //如果没超过最大层,并且存在子元素数组
    foreach ($children_elements[$id] as $child) {
      if (!isset ($newlevel)) { //第一次循环没设置变量$newlevel,所以把$newlevel设为true,并且开始子元素的开始代码;第二次及之后的循环,已经设置了$newlevel,就不会再添加子元素的开始代码。因为同一批循环时兄弟元素,所以只需要一个子元素开始代码,循环内容为并列关系。
        $newlevel = true;
        start_lvl($output);
      }
      display_element_template($child, $children_elements, $max_depth, $depth +1, $output); //$child作为参数,继续去寻找下级元素
    }
    unset ($children_elements[$id]); //用完释放变量,以后就不会重复判断该值了,递归后继续判断剩下的子元素
  }
  if (isset ($newlevel) && $newlevel) { //如果前面找到了子元素,这里就要执行子元素的结束代码
    end_lvl($output);
  }
  end_el($output); //当前评论的结束代码
}
function display_element_template($e, & $children_elements, $max_depth, $depth, & $output) {
  $id = $e[&#39;id&#39;];
  display_element($e, $children_elements, $max_depth, $depth, $output);
  if ($max_depth <= $depth +1 && isset ($children_elements[$id])) { //如果超出最大层级,并且子元素存在的话,以$child为参数继续往下找
    foreach ($children_elements[$id] as $child) {
      display_element_template($child, $children_elements, $max_depth, $depth, $output);
    }
    unset ($children_elements[$id]); //用完释放变量
  }
}
function comments_list($comments) {
  $top_level_elements = array ();
  $children_elements = array ();
  foreach ($comments as $e) {
    if (0 == $e[&#39;parent&#39;]) {
      $top_level_elements[] = $e;
    } else {
      $children_elements[$e[&#39;parent&#39;]][] = $e;
    }
  }
  $output = &#39;&#39;;
  foreach ($top_level_elements as $e) {
    display_element_template($e, $children_elements, 2, 0, $output);
  }
  //var_dump($children_elements);//由于每次用完$children_elements后都会释放变量,所以到最后$children_elements为空数组
  return $output;
}
echo &#39;<ol class="comment-list">&#39;, comments_list($comments), &#39;</ol>&#39;;
로그인 후 복사

이것이 전부입니다. 실제로 일부 오픈 소스 cms를 참고할 수도 있습니다. . 좋은 코드가 많이 있습니다. 앞으로 모든 사람들이 PHP 중국어 웹사이트를 지원하기를 바랍니다.

관련 권장 사항:

PHP는 데이터베이스 추가, 삭제, 쿼리 및 수정 기능과 완전한 코드 PHP 예제를 구현합니다.


PHPMAILER는 PHP 이메일 기능을 구현합니다. php 예제


php-app 개발 인터페이스 암호화 자세한 설명_php 기술



위 내용은 PHP 무제한 주석 중첩 구현 코드 PHP 기술의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿