You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP嵌套评论递归函数失效问题求助

问题:PHP嵌套评论递归函数未生效,仅显示主评论

我尝试用PHP实现嵌套评论展示,每条评论包含id和parent_id字段:主评论的parent_id为0,回复评论的parent_id对应被回复评论的id。比如处理id为50的评论时,应调用递归函数并将新的parent_id设为50,遍历到id为58的评论时应满足条件并缩进显示。但目前递归逻辑完全未生效,仅能显示parent_id为0的主评论。

相关代码

if($result) 
{
  $commentsArr = mysqli_fetch_all($result, MYSQLI_ASSOC);
  echo displayIndentedComments($commentsArr);
}


function displayIndentedComments($commArr, $parent_id = 0, $indent = 0) 
{
  
  $commentHTML = '';
  
  foreach ($commArr as $comment) 
  {

    $username = $comment['username'];
    $timestamp = date("M j, Y, h:i A", strtotime($comment['submit_date']));
    $commentText = $comment['content'];
    $commentId = $comment['id'];
    $commentParentId = $comment['parent_id'];
          
    if($commentParentId == $parent_id) 
    {
      
      $marginLeft = 10 * $indent;
      $marginLeftAttr = $marginLeft . 'px';
      $commentHTML .= "<div id='$commentId' style='margin-top: 30px; margin-bottom: 30px; margin-left: $marginLeftAttr;'>
        <b style='color: LightSeaGreen;' >$username</b> - <span style='font-size: 13px;'>$timestamp</span><br>
              
        <div class='container m-0 p-0'  style='max-width: 900px;'>
          <div class='row'>
            <div style='margin: auto;' class='col-9'>
              <div class='mt-1'>$commentText</div> 
          </div>
            <div class='col-3' style='text-align: right;'>
              <button id='replyButton' onclick='showReplyCommentBox(this)' style='background: none; border: none;'><i class='fa fa-reply' aria-hidden='true'></i></button>
            </div>
          </div>
        </div>
              
        <p class='border-bottom mt-2'></p>
      </div>
    ";
    
      displayIndentedComments($commArr, $commentId, $indent + 1);
    }
  }
        
  return $commentHTML;
}

评论数据

[
{"id":"60","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 13:00:01"},
{"id":"59","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 12:58:52"},
{"id":"58","page_id":"1","parent_id":"50","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 12:56:10"},
{"id":"57","page_id":"1","parent_id":"53","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 12:55:50"},
{"id":"56","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 11:49:12"},
{"id":"55","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 11:45:44"},
{"id":"54","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 11:38:11"},
{"id":"53","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 11:37:02"},
{"id":"52","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 11:08:56"},
{"id":"51","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 11:01:50"},
{"id":"50","page_id":"1","parent_id":"0","username":"abc","content":"Lorem ipsum","submit_date":"2023-11-10 10:59:13"}
]

解决方案

核心问题1:递归调用未拼接返回的HTML

你在递归调用displayIndentedComments时,仅执行了函数但未将其返回的子评论HTML内容拼接到$commentHTML变量中,导致子评论的代码根本没被包含到最终输出里。

修改方式:把递归调用的返回值追加到$commentHTML:

// 原代码
// displayIndentedComments($commArr, $commentId, $indent + 1);

// 修改后
$commentHTML .= displayIndentedComments($commArr, $commentId, $indent + 1);

核心问题2:类型不匹配导致的比较失败

从评论数据可以看到,parent_id是字符串类型(比如"50"),而递归时传递的$parent_id默认是整数0,后续传递的$commentId如果也是字符串类型,用==虽然能自动转换,但为了避免意外,最好统一类型后再比较:

if((int)$commentParentId === (int)$parent_id) 

修改后的完整函数

function displayIndentedComments($commArr, $parent_id = 0, $indent = 0) 
{
  
  $commentHTML = '';
  
  foreach ($commArr as $comment) 
  {

    $username = $comment['username'];
    $timestamp = date("M j, Y, h:i A", strtotime($comment['submit_date']));
    $commentText = $comment['content'];
    $commentId = $comment['id'];
    $commentParentId = $comment['parent_id'];
          
    // 统一类型后严格比较
    if((int)$commentParentId === (int)$parent_id) 
    {
      
      $marginLeft = 10 * $indent;
      $marginLeftAttr = $marginLeft . 'px';
      $commentHTML .= "<div id='$commentId' style='margin-top: 30px; margin-bottom: 30px; margin-left: $marginLeftAttr;'>
        <b style='color: LightSeaGreen;' >$username</b> - <span style='font-size: 13px;'>$timestamp</span><br>
              
        <div class='container m-0 p-0'  style='max-width: 900px;'>
          <div class='row'>
            <div style='margin: auto;' class='col-9'>
              <div class='mt-1'>$commentText</div> 
          </div>
            <div class='col-3' style='text-align: right;'>
              <button class='replyButton' data-comment-id='$commentId' onclick='showReplyCommentBox(this)' style='background: none; border: none;'><i class='fa fa-reply' aria-hidden='true'></i></button>
            </div>
          </div>
        </div>
              
        <p class='border-bottom mt-2'></p>
      </div>
    ";
    
      // 拼接递归返回的子评论HTML
      $commentHTML .= displayIndentedComments($commArr, $commentId, $indent + 1);
    }
  }
        
  return $commentHTML;
}

额外优化建议

  • 避免在循环中重复处理日期,可提前预处理评论数组,将日期格式好后再传入函数
  • 不要使用内联样式,建议将样式写到CSS类中(比如.comment-indent-1、.comment-indent-2)来控制左边距,更易维护
  • 注意id='replyButton'重复的问题,页面中id必须唯一,建议改成class='replyButton'并添加data-comment-id='$commentId'属性,在JS中通过该属性获取评论id

内容的提问来源于stack exchange,提问作者user22894700

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:04:50