>백엔드 개발 >PHP 튜토리얼 >PHP에서 무제한 주석 중첩을 구현하는 단계에 대한 자세한 설명

PHP에서 무제한 주석 중첩을 구현하는 단계에 대한 자세한 설명

php中世界最好的语言
php中世界最好的语言원래의
2018-05-16 15:51:442515검색

이번에는 PHP에서 무한 주석 중첩을 구현하는 단계에 대해 자세히 설명하겠습니다. 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;;

이 기사의 사례를 읽으신 후 방법을 마스터하셨다고 생각합니다. 더 흥미로운 정보를 보려면 다른 관련 항목에 주의하세요. PHP 중국어 웹사이트의 기사!

추천 자료:

csrf-token 확인 시뮬레이션 제출 예제를 사용한 php 컬 자세한 설명


php 데이터베이스 추가, 삭제, 쿼리 및 수정을 구현하는 자세한 단계

위 내용은 PHP에서 무제한 주석 중첩을 구현하는 단계에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.