当前位置:首页 > 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)
);

邻接表实现方案

添加评论

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;
}

闭包表实现方案

添加评论

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>';
    }
}

性能优化建议

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

php实现多级评论

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

无限层级实现

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

标签: php
分享给朋友:

相关文章

php实现栈

php实现栈

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

php实现的分页

php实现的分页

PHP 实现分页的方法 基本分页逻辑 分页的核心在于计算总页数、当前页码以及数据偏移量。假设每页显示 10 条数据: $current_page = isset($_GET['page']) ? (…

php 实现秒杀

php 实现秒杀

PHP 实现秒杀的关键技术 秒杀系统需要解决高并发、超卖、性能瓶颈等问题。以下是实现秒杀的核心方案: 使用 Redis 预减库存 将商品库存提前加载到 Redis 中,通过原子操作保证库存准确性:…

php 实现md5

php 实现md5

使用 PHP 内置函数实现 MD5 PHP 提供了 md5() 函数,可以直接计算字符串的 MD5 哈希值。该函数接受一个字符串参数,返回 32 字符的十六进制哈希值。 $string = "H…

php session实现购物车

php session实现购物车

PHP Session 实现购物车 初始化 Session 确保在使用 Session 前调用 session_start() 函数。通常放在 PHP 文件的最顶部。 <?php sessio…

php搜索功能的实现

php搜索功能的实现

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