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
相关产品推荐
相关产品推荐

