php表设计实现短视频评论区完整功能

 更新时间:2023年07月19日 14:13:57   作者:北桥苏  
这篇文章主要为大家介绍了php表设计实现短视频评论区完整功能示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

现如今,不管是哪种类型的应用,评论区都少不了。从工具类的到媒体信息流类的,评论留言都是最基本的互动环节。比如抖音短视频下,针对视频每个用户都可以发表自己的观点;而针对用户的评论,其他的用户又可以对其进行评论,依次回复下去。       

那么,一个视频的评论回复的表如何设计?功能如何实现呢?如标题,这里是用一张表完成,但是在我完成功能后发现拆成两个张更合适(评论表和回复表),这个后面已经改了,最后也会说一下。

效果

页面上展示是,视频下分页展示第一级的评论列表,评论下的评论是进行折叠,点击“查看全部”分页显示所有层级的评论。一张表的设计下,评论下的评论下……的评论是通过关联上一级主键的,也就是递归的方式。

但是下面的是只要是对评论进行评论都放在第一级的评论下,而递归是树形结构。虽然也能通过对树形结构数据处理拉伸到二季下,但是在底下评论特别多的情况就会体验特别差。所以针对这个我对表格加了一个面包屑字段,表结构如下,然后再分次完成评论数据的如何添加,按页面方式查询的。

表结构

CREATE TABLE `short_video_comment` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pid` int(11) DEFAULT '0' COMMENT '父级ID',
  `crumbs` json DEFAULT NULL COMMENT '面包屑',
  `video_id` int(11) DEFAULT '0',
  `user_id` int(11) DEFAULT '0',
  `commented_user_id` int(11) DEFAULT '0' COMMENT '被评论者用户ID',
  `is_pubisher` tinyint(1) DEFAULT '0' COMMENT '是否作者',
  `content` varchar(255) DEFAULT '' COMMENT '评论',
  `state` int(1) DEFAULT '1' COMMENT '1. 显示  0. 隐藏',
  `like_count` int(11) DEFAULT '0' COMMENT '点赞数',
  `create_time` int(11) DEFAULT '0' COMMENT '创建时间',
  `delete_time` int(11) DEFAULT '0' COMMENT '删除时间',
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=282 DEFAULT CHARSET=utf8mb4 COMMENT='用户评论记录表';

如上图的 “crumbs” 字段是一个数组方式的json,也就是添加时会记录当前评论的关系链,从最顶层ID到最近的上一级。而实现分页显示第二级下的所有评论,只需要把 “crumbs” 索引为1的pid作为查询条件就能找到该id下的所有评论,如下是查询二级评论ID为285的所有评论列表。

select * from short_video_comment where json_extract(crumbs, "$[1]") = 285

而对于关于crumbs如何存入和谁回复谁,就只需要在评论添加的时候,对上一级评论ID进行递归查询所有上级ID放入 "crumbs", 被回复者就更好办了,查询上一级评论的评论者ID(user_id),放入当前评论记录的 "commented_user_id",展示的时候只需要关联一下用户信息表就可以了,接下来就是业务代码演示了。 

代码演示

▲评论添加

public static function commentAdd($videoInfo, $userId, $content, $commentInfo = [])
{
    $commentId = 0;
    $videoId = $videoInfo['id'] ?? 0;
    $publisherId = $videoInfo['user_id'] ?? 0;
    try {
        $crumbs = [0];
        if ($commentInfo) {
            $pid = $commentInfo['id'] ?? 0;
            $insert['commented_user_id'] = $commentInfo['user_id'] ?? 0;
            $insert['pid'] = $pid;
            $crumbs = ShortVideoComment::getCrumbs($pid);
        }
        $insert['video_id'] = $videoId;
        $insert['user_id'] = $userId;
        $insert['is_pubisher'] = $userId == $publisherId ? 1 : 0;
        $insert['content'] = $content;
        $insert['state'] = ShortVideoComment::STATE['SHOW'];
        $insert['create_time'] = time();
        $insert['crumbs'] = json_encode($crumbs);
        $commentId = ShortVideoComment::insertGetId($insert);
        if ($commentId && $videoId) {
            $map[] = ['id', '=', $videoId];
            ShortVideoModel::where($map)->setInc('comment_count');
            $userId && self::setRating(6, $userId, $videoId);
        }
    } catch (\Exception $e) {
        $preFileName = str::snake(__FUNCTION__);
        $path = self::getClassName();
        write_log("msg:" . $e->getMessage(), $preFileName . "_error", $path);
    }
    return $commentId;
}

▲获取面包屑

public static function getCrumbs($cateId = 0, &$ids = [])
{
    $idArr = array_merge((array)$cateId, $ids);
    $info = self::where('id', $cateId)->find();
    if ($info['pid'] != 0) {
        $idArr = self::getCrumbs($info['pid'], $idArr);
    } else {
        array_unshift($idArr, 0);
    }
    return $idArr;
}

▲数据查询

public static function getList($map, $page = 1, $size = 30, $pid = 0)
{
    $where[] = ['delete_time', '=', 0];
    $where[] = ['state', '=', self::STATE['SHOW']];
    $map = array_merge($where, $map);
    $field = ['id,crumbs,pid,video_id,user_id,commented_user_id,content'];
    $queryObj = self::field($field)
        ->with([
            'user' => function ($query) {
                $query->withField('id, nickname, avatar, mobile');
            },
            'commented_user' => function ($query) {
                $query->withField('id, nickname, avatar, mobile');
            }
        ])
        ->where($map);
    $pid && $queryObj->whereRaw("JSON_EXTRACT(`crumbs` ,'$[1]') = $pid");
    $list = $queryObj->page($page, $size)
        ->order('like_count desc')
        ->select();
    return $list;
}

写在最后

以上是初版时候根据业务设计的表格,后来的评论区完全仿照某音,所以也就对表格进行了拆分。分成了评论表和回复表,只要是对评论进行评论就是回复,这样在后面数据庞大的时候,性能会更好一点。但是如何是前期设计的就是一张表,而迭代的时候也要有某音评论的效果,可以作为解决方法尝试滴,更多关于php短视频评论区功能的资料请关注脚本之家其它相关文章!

相关文章

  • 详解php魔术方法(Magic methods)的使用方法

    详解php魔术方法(Magic methods)的使用方法

    有些东西如果不是经常使用,很容易忘记,比如魔术方法和魔术常量,这篇文章主要介绍了php魔术方法(Magic methods)的使用方法,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • 浅析php面向对象public private protected 访问修饰符

    浅析php面向对象public private protected 访问修饰符

    本篇文章是对php面向对象public private protected 访问修饰符进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • PHP实现防重复提交(防抖)的方法总结

    PHP实现防重复提交(防抖)的方法总结

    当涉及到处理表单提交或用户点击按钮等操作时,防抖(Debounce)是一种重要的技术,它可以有效地防止不必要的重复操作,本文为大家整理了 PHP 中防抖的多种实现方法,需要的可以参考下
    2023-09-09
  • PHP实现通过文本文件统计页面访问量功能示例

    PHP实现通过文本文件统计页面访问量功能示例

    这篇文章主要介绍了PHP实现通过文本文件统计页面访问量功能,涉及php文件读写、数值计算及图形操作相关实现技巧,需要的朋友可以参考下
    2019-02-02
  • PHP 数字左侧自动补0

    PHP 数字左侧自动补0

    举例来说:员工的工号 X001 虽然 MySQL 本身的字段设定成 zerofill 的属性时,会将不足位数的部份补上0,但是这个功能只能用在数字的字段上面。 所以必要的时候只好靠PHP来进行了。
    2008-03-03
  • 解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示

    解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds

    最近做的程序中涉及到的循环比较多且处理的情况较复杂,在运行程序时出现执行超时提示如下:Fatal error: Maximum execution time of 30 seconds exceeded in D:\php\AppServ\www\sum3\test.php on line 3通过在网上搜索,找到了解决方法和大家分享,下面来一起看看吧。
    2016-11-11
  • php动态生成缩略图并输出显示的方法

    php动态生成缩略图并输出显示的方法

    这篇文章主要介绍了php动态生成缩略图并输出显示的方法,涉及php操作图片的相关技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • PHP7下安装并使用xhprof性能分析工具

    PHP7下安装并使用xhprof性能分析工具

    这篇文章主要介绍了PHP7下安装并使用xhprof性能分析工具,对性能感兴趣的朋友,可以研究下
    2021-04-04
  • php的mssql数据库连接类实例

    php的mssql数据库连接类实例

    这篇文章主要介绍了php的mssql数据库连接类,以一个类实例的形式演示了PHP实现针对mssql数据库的各种常用操作方法,包括对数据库的连接与增删改查等操作,非常具有实用价值,需要的朋友可以参考下
    2014-11-11
  • PHP可变函数的使用详解

    PHP可变函数的使用详解

    本篇文章是对PHP中可变函数的使用进行了详细的分析介绍,需要的朋友参考下
    2013-06-06

最新评论