当前位置: 首页 > 后端技术 > PHP

如何实现楼中楼评论系统

时间:2023-03-29 21:41:21 PHP

文章内容由蚊子的博客发布,或许你想看看他的其他博客:https://www.xiabingbao.com/comments/2017/09/01/blog-comments.html1.实施前的思考经过多次评论和网易云评论,最终下定决心写一个评论系统。在我们使用的众多评论系统中,目前比较流行的是build-in-build的方式,比如百度贴吧,wordpress等。在此之前,一楼、二楼、三楼一般都是按照时间顺序陈列的。如果要回复某人,用@符号标记用户名,然后回复内容。但是这种方式有一个很大的问题,讨论的问题没有聚集在一起,其他用户根本不知道你在讨论什么,原作者在1楼发表评论,等你进来回复这位用户的评论,你已经到10楼了。作者再回复你,你又在20楼了。其他用户看到10楼的时候,已经忘记原作者说了什么了。百度贴吧改版之前就是用这个方法,后来新版本启用了楼中楼的方法。这样就可以将某个话题的讨论集中在一个地方。同时,知乎也对他的评论系统进行了改版,但不是改成楼中楼,而是在每条评论后面加了一个弹窗链接,可以查看对话。点击链接后,弹窗可以看到这两个人互动的所有评论。以时间倒序显示评论或以正序平铺显示评论很容易实现,但难以阅读;在楼中楼显示评论对用户的阅读习惯更友好,但可能难以实现。但最终,我还是决定采用楼中楼的方式。虽然我博客的评论少得可怜,但我还是决定实施。2、数据表的设计从前后端使用的语言和框架入手。前端考虑页面渲染和更多的事件调用,使用Vue框架。vue应该不是最好的选择,毕竟对于一个有评论的前端部门来说可能有点大材小用,但是为了快速开发,我还是选择了vue。后台使用php语言,数据库使用mysql。数据库表的设计既要考虑到可以导入以前的数据,又要方便以后添加新的评论。这里我创建了3张表:文章表、用户表、评论表。在网易云的帖子被关闭之前,我导出了我的数据(我说的数据已经丢失了,不知道导出的格式是什么),我们来看看网易云的帖子中导出的数据格式:{"title":"从0到1学习node(7)express搭建一个简单的论坛","url":"www.xiabingbao.com/node/2017/02/20/node-express-forum.html","sourceId":","ctime":1487581007000,"comments":[{"cid":"72813956","ctime":1493107384000,"content":"本论坛对node版本有要求吗?我的节点比较老Errordownloadingyoursourcecode","pid":"0","ip":"xxx","port":0,"sc":"web","vote":0,"against":0,"anonymous":false,"user":{"userId":"1074123","nickname":"态度06q23q的网友","avatar":"","anonymous":false}},{"cid":"77196403","ctime":1493714822000,"content":"不确定,我的node版本是6.9.4,npm版本是3.10.10,尝试升级node版本","pid":"72813956","ip":"xxx","port":0,"sc":"web","vote":0,"against":0,"anonymous":false,"user":{"userId":"2414123","nickname":"small小dd蚊子","avatar":"http://cms-bucket.nosdn.127.net/1d6faddedb544cee93ff426a4aa2fe7620170322162349.jpg","anonymous":false}}]}从上面的数据可以看出每篇文章都有titles,urls,comments.一条评论的每一项都有自己对应的id,回复的评论pid,内容内容,评论的userid,昵称,头像.我这里只提取了主要信息输入2.1用户表用户表比较简单,需要考虑的是将原来的userid也保存为一个字段,这样在导入评论数据的时候可以找到对应的用户。评论数据后也导入了,就是这个字段可以删除,以后新添加的注册用户不会用到这个字段用户表设计:字段类型描述idintauto-increment,primarykeywidintuser'soriginaluseridnicknamevarchar(50)nicknameavatarvarchar(100)avatarstatusintstatusdesign创建用户表后,将原始数据中的所有用户分别取出,然后以userid为key存入数组,这样也可以达到去重的效果。将获取到的所有用户数据存储在user表中2.2Comment表在设计comment表时,主要考虑以下因素:comments必须依赖articles和users存在,所以comments的外键是articleID和userid,以及留言板是一个空文章内容的评论表单;我觉得以后新的评论可以使用自增id,而不是跟着原评论的cid生成新的评论id,所以这次评论表的主键是id,而原评论的id只是用作场域之一,构建建筑物中建筑物之间的关系。当这些旧的评论插入到数据表中,就会有新的评论id;建筑物中的建筑物的评论在某个评论下。同时楼中楼也有相互之前的互动回复。因此,这条评论的pid(parentid)表示当前评论在哪个评论下,replyid表示回复了哪个评论;如果评论不是父评论,那么pid是父评论的id,replyid是回复评论的id;当pid或replyid为0时,表示直接评论文章。因此,我们的评论表是这样设计的:fieldtypedescriptionidint自增,主键widintcomment原始主键ciduidintuseridreplyidint评论回复的评论id,0pidint如果没有评论则为评论的parentid,以及0aidvarchar如果没有(100)文章IDcontentvarchar(300)评论内容createtimeint评论时间的时间戳表中的aid(文章ID)可以是文章的url,文章的id或者其他任何可以唯一标识文章。这里我们使用文章的uri作为唯一标识。比如上面数据中的文章,我们使用/node/2017/02/20/node-express-forum.html来标识文章。其他文章也是如此。在将这些评论写入表中时,还要注意在原始数据中,每条评论对应一个用户。在我设计的系统中,用户和评论是分开的,只用uid做关联。新用户和新评论都使用自己的自增主键。因此,在将原始评论存入数据库时??,需要将原来的userid转换为新用户表中的主键id,统一新旧数据。文章表不解释。3、具体实现前端部分主要负责显示每篇文章的评论,同时允许登录用户添加评论。3.1显示评论我们为每条评论添加了一个文章标识,前端可以根据帮助获取当前文章的所有评论。但是,我们的评论是以楼中楼的方式展示的,单脑无法将数据扁平化到页面中。我们在2.2也说过,pid为0的评论都是直接对文章的评论,这些评论应该显示为一级评论;其他数据pid的一定是属于某个comment的,应该在buildingdisplay中显示为Building。同时,无论是一级评论还是楼内楼的评论,都可能存在分页,所以这里也要处理分页。所以最终我们在前端得到的结构应该大致是这样的:{code:0,data:[{//一级评论id:1,content:'蚊子的博客真棒',createtime:'20170800:26onAugust08',nickname:'Anonymous',reply:{//buildinginbuildingdata:[id:1,content:'谢谢大家一起学习',createtime:'2017-08-0800:36',nickname:'mosquito'],page:{cur_page:1,all_page:1}}}],page:{cur_page:1,all_page:1}}前端拿到接口返回的数据后,它可以渲染页面。在头像的处理中,也考虑到了https环境,所以返回的头像链接都是以//开头的形式。3.2参与评论用户对一篇文章或评论产生了共鸣,需要留言讨论,我们需要用户能够添加自己的评论。评论的类型,如果细分的话,可以分为3类:直接评论文章,pid和replyid为空;回复一级评论,pid和replyid为一级评论的id;在楼里回复楼,pid是一级评论的id,replyid是你回复的评论的id。这里的前端实现是指oschina(开源中国)的注释方式。直接评论文章,直接在顶部的评论窗口输入;回复其他评论时,使用弹窗回复。弹出回复的好处是页面不需要滚动,用户对某个评论的感知可以停留在这个位置;同时,不需要再增加各种不必要的小输入框供用户输入评论。3.3登录在登录的问题上,我也纠结了很久。我应该使用自己的登录系统,还是使用第三方登录,或??者用户不需要注册和登录,只需要输入他们的邮箱和昵称就可以发表评论?如果使用自己的评论系统,需要开发一个注册登录的流程,开发起来比较麻烦,而且对于想要回复一句话的用户,可能会直接放弃注册;如果你只能通过输入你的电子邮件地址和昵称来评论,我考虑到用户可能产生的无限评论,没有控制。所以最终还是考虑接入第三方登录。这里我们选择使用微博作为第三方登录入口,后面会考虑添加github账号登录。关于如何接入微博第三方登录,我们下篇文章再说。文档已完成。对于不熟悉的开发者来说,一开始可能会有点迷惑,但应该问题不大。3.4增加邮箱功能用户登录第三方成功后,名字旁边有一个小输入框,可以让用户输入邮箱接收回复提醒。此输入完全是自愿的,即使不输入电子邮件地址也可以发表评论。又考虑到本站是个小站,流量很低,用户可能一时兴起评论几句,过后又想起本站,不知道怎么找。于是想着加个邮件提醒功能,防止大神的评论沉入大海。3.5特别注意前端引入Vue框架,每个文章页面都会加载评论模块。为了不让评论模块中的vue库影响外部资源(比如版本冲突等),我先把全局变量给wzVue,然后取消Vue:wzVue=Vue;delete(Vue);delete(window.Vue);同时,在最初实现评论功能的时候,只要用户进入这个页面,就会加载评论。但是有一个问题,用户不一定会看到你的文章到底,或者只是看你的评论。所以后来文章改成了按需加载,只有当用户滚动到底部想看评论时,才加载评论。最终的展示效果是这样的:4.总结作为一个前端开发者,只具备后端知识开发一个博客评论系统是非常简单的,整个框架的设计感觉比较粗糙。同时,缓存系统不熟练,无法即时更新评论信息。该系统还有很大的改进空间。欢迎您对蚊子(史少兵)发表意见和建议。写这篇文章的时候想着以后版本修改的时候,可以做成评论的同步加载方式。生成的文章更新频率很低,甚至变化不大,所以缓存的是评论的内容。每当有新的评论时,删除当前文章的缓存,重新加载新的数据,再缓存新的数据,这样当评论数据更新比较少的时候,可以缓存更长时间,也有利于评论内容的搜索爬取。文章内容由Mosquito的博客发布,或许你想看看他的其他博客:https://www.xiabingbao.com/comments/2017/09/01/blog-comments.html