今回は、PHP で無限コメントのネストを実装する手順について詳しく説明します。PHP で無制限のコメント ネストを実装するための 注意事項 は何ですか? ここで実際のケースを見てみましょう。
BBを設計する過程で、ここのアルゴリズムが最適化されていない場合、致命的な結果を招く可能性があるため、再帰なしで無限の分類構造表示と親子構造検索を実現できるかどうかを考えてきました。想像してみてください。記事に 300 個のコメントがある場合、通常の再帰アルゴリズムによれば、データベースは少なくとも 301 回クエリされる必要があります。これは、ネストのレベルが 1 つまたは 2 つある場合、またはコメントの数が 1,000 を超える場合です。 、データベースがクラッシュするだけではないでしょうか?実際、PHP の強力な配列処理機能は、この問題を迅速かつ便利に解決するのにすでに役立っています。以下の図は、無限に分類されたデータベース構造を示しています:
記事 ID 8 のコメント 108 件
21 ID 1 のコメントへの 8 件の返信 ID 2 のコメントへの 328 件の返信
記事番号 8 のコメントを表示するにはネストされた方法でフロントエンドを作成する場合、実際に必要なのはデータベースへのクエリは 1 回 (つまり "SELECT * FROM TABLE WHERE newsID=8") だけであり、その後の再帰作業は強力な
PHP 配列
このコードを以下の 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 ( '0' != $result[$i]['parentId'] ) { $this->addChildenToCommentsAry($result, $result[$i]['parentId'], $result[$i]); unset($result[$i]); } $i++; } $result = array_values($result); /* 重组结束 */
実装方法 2
コアコードは WordPress から抽出されています
<?php $comments = array ( array ( 'id' => '3', 'parent' => '0' ), array ( 'id' => '9', 'parent' => '0' ), array ( 'id' => '1', 'parent' => '3' ), array ( 'id' => '2', 'parent' => '3' ), array ( 'id' => '5', 'parent' => '1' ), array ( 'id' => '7', 'parent' => '1' ) ); function html5_comment($comment) { echo '<li>'; echo 'id:', $comment['id'], ' parent:', $comment['parent']; } 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 .= '<ol class="children">' . "\n"; } function end_lvl(& $output) { $output .= "</ol><!-- .children -->\n"; } function display_element($e, & $children_elements, $max_depth, $depth, & $output) { $id = $e['id']; 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['id']; 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['parent']) { $top_level_elements[] = $e; } else { $children_elements[$e['parent']][] = $e; } } $output = ''; 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 '<ol class="comment-list">', comments_list($comments), '</ol>';
CSRFトークン検証シミュレーション送信例を使用したphpのカールの詳細な説明
phpデータベースの追加、削除、クエリ、および変更を実装するための詳細な手順
以上がPHP で無制限のコメントのネストを実装する手順の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。