当前位置:首页 > PHP

php实现多级评论

2026-03-13 06:34:18PHP

实现多级评论的数据库设计

多级评论需要递归或嵌套的数据结构。常见的数据库设计方案有两种:

邻接表模型(Adjacency List)

CREATE TABLE comments (
    id INT AUTO_INCREMENT PRIMARY KEY,
    content TEXT NOT NULL,
    parent_id INT DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (parent_id) REFERENCES comments(id) ON DELETE CASCADE
);

闭包表模型(Closure Table)

CREATE TABLE comments (
    id INT AUTO_INCREMENT PRIMARY KEY,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE comment_tree (
    ancestor INT NOT NULL,
    descendant INT NOT NULL,
    depth INT NOT NULL,
    PRIMARY KEY (ancestor, descendant),
    FOREIGN KEY (ancestor) REFERENCES comments(id),
    FOREIGN KEY (descendant) REFERENCES comments(id)
);

邻接表实现方案

添加评论

php实现多级评论

function addComment($content, $parentId = null) {
    $stmt = $pdo->prepare("INSERT INTO comments (content, parent_id) VALUES (?, ?)");
    $stmt->execute([$content, $parentId]);
    return $pdo->lastInsertId();
}

递归获取评论树

function getComments($parentId = null) {
    $stmt = $pdo->prepare("SELECT * FROM comments WHERE parent_id " . ($parentId ? "= ?" : "IS NULL"));
    $stmt->execute($parentId ? [$parentId] : []);

    $comments = [];
    while ($comment = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $comment['replies'] = getComments($comment['id']);
        $comments[] = $comment;
    }
    return $comments;
}

闭包表实现方案

添加评论

php实现多级评论

function addCommentWithClosure($content, $parentId = null) {
    $pdo->beginTransaction();

    $stmt = $pdo->prepare("INSERT INTO comments (content) VALUES (?)");
    $stmt->execute([$content]);
    $commentId = $pdo->lastInsertId();

    if ($parentId) {
        $stmt = $pdo->prepare("
            INSERT INTO comment_tree (ancestor, descendant, depth)
            SELECT ancestor, ?, depth+1 FROM comment_tree WHERE descendant = ?
            UNION ALL SELECT ?, ?, 0
        ");
        $stmt->execute([$commentId, $parentId, $commentId, $commentId]);
    } else {
        $stmt = $pdo->prepare("INSERT INTO comment_tree (ancestor, descendant, depth) VALUES (?, ?, 0)");
        $stmt->execute([$commentId, $commentId]);
    }

    $pdo->commit();
    return $commentId;
}

获取评论树

function getCommentTree() {
    $stmt = $pdo->query("
        SELECT c.*, ct.depth 
        FROM comments c
        JOIN comment_tree ct ON c.id = ct.descendant
        WHERE ct.ancestor = (SELECT ancestor FROM comment_tree WHERE depth = 0 LIMIT 1)
        ORDER BY ct.ancestor, ct.depth
    ");
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

前端展示方案

递归输出HTML

function displayComments($comments, $level = 0) {
    foreach ($comments as $comment) {
        echo '<div style="margin-left: ' . ($level * 20) . 'px">';
        echo htmlspecialchars($comment['content']);
        if (!empty($comment['replies'])) {
            displayComments($comment['replies'], $level + 1);
        }
        echo '</div>';
    }
}

性能优化建议

对于大型评论系统,邻接表模型的递归查询可能导致性能问题。可以考虑以下优化:

  1. 使用闭包表替代邻接表
  2. 为parent_id字段添加索引
  3. 实现缓存机制(如Redis)
  4. 使用预加载技术批量获取数据
  5. 限制递归深度或实现分页加载

无限层级实现

上述两种方案都支持无限层级评论。邻接表方案更简单但查询效率较低,闭包表方案写入复杂但查询高效。根据项目规模选择合适方案。

标签: php
分享给朋友:

相关文章

php实现递归

php实现递归

递归的基本概念 递归是一种函数调用自身的技术,适用于解决可以分解为相同子问题的问题。在PHP中,递归需要明确的终止条件(基线条件),否则会导致无限循环。 递归实现阶乘 阶乘是经典的递归案例,n! =…

php实现定时任务

php实现定时任务

PHP 实现定时任务的几种方法 在 PHP 中实现定时任务可以通过多种方式完成,具体选择取决于项目需求和服务器环境。以下是常见的实现方法: 使用 Cron 任务 Cron 是 Linux 系统中常用…

php实现栈

php实现栈

栈的基本概念 栈(Stack)是一种遵循后进先出(LIFO)原则的数据结构。核心操作包括: push:元素入栈。 pop:元素出栈(返回并移除栈顶元素)。 peek:查看栈顶元素(不移除…

php 实现接口

php 实现接口

PHP 实现接口的方法 在 PHP 中,接口(Interface)用于定义一组方法的规范,而不包含具体的实现。类可以实现(implement)接口,并必须实现接口中定义的所有方法。 定义接口 接口通…

php怎么实现登录功能

php怎么实现登录功能

数据库准备 创建用户表存储登录信息,通常包括用户名、密码(需加密)等字段。示例SQL: CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY…

php搜索功能实现的

php搜索功能实现的

PHP 搜索功能实现方法 数据库搜索实现 使用 SQL 的 LIKE 语句进行模糊匹配,适用于小型网站和简单搜索需求。 $searchTerm = $_GET['search']; $query =…