无限极评论怎么删除php,PHP:打造一个无限极评论模块

我的毕设项目的评论模块原来是采用多说插件完成的,但是我现在希望能够自己管理评论内容,所以自己开始写评论模块。具体准备采用与简书下评论类似的结构,即一级评论直接显示在文章下方,而二三级评论显示在一级评论的下方,如下图所示:

a3b45973902ae437cc95ab19da49534e.png

我觉得这可以说是无限极分类的一种运用,准确的说是子孙树的运用,进行子孙树分类后,循环输出内容,形成评论(不懂无限极分类的朋友可以去看看我的文章无限极分类原理与实现)。

当然,真正完成无限极回复评论的功能还有其他的要点,下面就来说说我是怎么完成无限极评论的。

数据库设计

首先,就是数据表的设计。如果是论坛系统,可以将评论的数据分割成两个表,一个表存储评论的信息,包括发布帖子的用户id或回复的用户id,回复的帖子id,回复的时间等;另一个表,存储评论的内容,包括帖子的主题和回复的内容。

我完成的是文章的评论模块,就没分成两个表了,直接将评论的内容与信息放在一起,如下面结构:

| 列名 | 列类型 | 列属性 | 说明 | |------|--------|------- | | comm_id| INT | UNSIGNED PRIMARY KEY AUTO_INCREMENT | 主键 | user_id | INT | UNSIGNED NOT NULL DEFAULT 0 | 用户id | parent_id | INT |UNSIGNED NOT NULL DEFAULT 0| 评论的父级 | artcile_id | INT |UNSIGNED NOT NULL DEFAULT 0| 评论的文章id | comm_cont | TEXT | | 评论的内容 | comm_time | INT | UNSIGNED NOT NULL DEFAULT 0 | 评论发布的时间

SQL语句:

CREATE TABLE comment (

comm_id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,

user_id INT UNSIGNED NOT NULL DEFAULT 0 ,

parent_id INT UNSIGNED NOT NULL DEFAULT 0 ,

article_id INT UNSIGNED NOT NULL DEFAULT 0 ,

comm_cont TEXT,

comm_time INT UNSIGNED NOT NULL DEFAULT 0

) ENGINE=MYISAM CHARSET=UTF8 ;

复制代码

这种结构是完成无限极回复的基础,也能够很明显的看出取出的数据能很好的进行无限极分类。

评论的结构分析

完成一个评论模块是很容易的,评论放入数据库,然后取回放置在html中,同样能完成评论模块。但是,这种结构是很杂乱,无序的。要想完成如简书评论一样的评论模块,就得采用特殊的方式。

那么,就要好好观察一下简书评论的结构了。

a3b45973902ae437cc95ab19da49534e.png

结合上面的数据表结构,可以推断一下,从数据表中取出且无限极分类后的数据,它的结构应该是这样的:

array (

array(一级评论,

child=>array(

二级评论,

三级评论

)

),

array (

一级评论 ,

child=>array(

)

……

复制代码

为什么这么说?你可以很明显的看出,二级、三级评论被包裹在一级评论中,而二级、三级评论是平行关系;因此,二级、三级评论是一级评论的子孙节点,而二级、三级评论是平行节点,不存在父子关系。

因此,可以得出,分类后的数据有且只有一个子孙节点,多级评论无论是不是对一级评论进行回复,只要是处于一级评论的范围,那么它的父节点必然是一级评论。

那么,二级、三级回复中的@某某某又是怎么实现的?其实,我在这里困扰了很长时间。我期望用对表的自身连接来完成,但是不行,破坏了上面所述的结构。最后,我从简书请求的json数据中得到了答案,请看简书评论的json数据:

8ddd2210d84e63715a4f20310c4bdf9d.png

上传后有点模糊,各位同学可以借助火狐或者谷歌浏览器上面的插件观察JSON数据。

重点观察compiled_content字段,可以推断它是将@某某某直接存储到数据库中的。这样问题就解决了,同时观察json数据,也能够验证我上面所述的结构是正确的。

具体实现

分析完结构就来说说具体怎么来完成无限极回复。第一步,一级评论形成,这个简单,直接将评论存储即可

406f0582817be59571f74c5bf329a281.png

而二级评论要利用到js,点击评论时,获取一级评论的用户名,并保存,在发布回复时注意将其和评论的内容结合在一起发往后台:

e0c38325286bead4e7dfc5a4c813d04c.png

// replyUser 即 被回复的用户名 @xxxx

var content = $('#reply').val.split(replyUser)[1];

var userlink = '' + replyUser + '';

var comm_cont = encodeURIComponent(userlink+content);

复制代码

那么在数据库中表现如下:

da0f96871464e26315d9d77090a7eb8c.png

之后就是一个关键点,利用子孙树进行分类,分类函数如下:

/**

* @param $data array 数据

* @param $parent string 父级元素的名称 如 parent_id

* @param $son string 子级元素的名称 如 comm_id

* @param $pid int 父级元素的id 实际上传递元素的主键

* @return array

*/

function getSubTree($data , $parent , $son , $pid = 0) {

$tmp = array();

foreach ($data as $key => $value) {

if($value[$parent] == $pid) {

$value['child'] = getSubTree($data , $parent , $son , $value[$son]);

$tmp[] = $value;

}

}

return $tmp;

}

复制代码

如此分类后,数据结构发生变化,大致如下:

7ebc262f3b6938189f144db8d9a7d2e6.png

拥有这种结构就能很好去完成评论了,如下

<?php foreach($tree as $key=>$val) ?>

<?php echo $val['user_name'];?>

<?php foreach($val['child'] as $k=>$v) ?>

复制代码

同时,形成的回复样式如下所示:

c27464f9fefb1c0d5df1c9afad69606f.png

这样类简书评论结构的无限极回复就完成了。

PS

这只是评论的一种形式,如还有一种类楼梯式的结构,这种实现则更为简单一点,如下图:

cde2fb3e30ebae67fcbda37913e18b19.png

这种结构就很容易完成,只要存储数据库中的parent_id完全等于你回复的comm_id,在经过如下无限极分类,就能够完成。

/**

* 子孙树

*/

function getSubTree($data , $parent , $son , $pid = 0, $lev = 0) {

$tmp = array();

foreach ($data as $key => $value) {

if($value[$parent] == $pid) {

$value['lev'] = $lev;

$tmp[] = $value;

$tmp = array_merge($tmp , getSonTree($data , $parent , $son , $value[$son] , $lev+1));

}

}

return $tmp;

}

复制代码

这种无限极子孙树分类和前面给出的子孙树分类不同,分类后不会将子类包裹在child中,而是形成等级,最高级为0,依次往下。

例如:一级评论的comm_id=1,parent_id=0,那么二级评论的comm_id=2,parent_id=1;三级评论的comm_id=3,parent_id=2;

分类最后形成如下结构

array(

array('comm_id'=>1,parent_id=>0,art_id=>1,'lev'=>0) ,

array('comm_id'=>2,parent_id=>1,art_id=>1,'lev'=>1),

array('comm_id'=>3,parent_id=>2,art_id=>1,'lev'=>2),

array('comm_id'=>4,parent_id=>3,art_id=>1,'lev'=>3),

array('comm_id'=>5,parent_id=>2,art_id=>1,'lev'=>2)

);

复制代码

然后直接循环输出,并将lev作为属性打印在html中,最后利用js读取lev,并根据不同的等级分配不同的margin-left即可,它会随着margin的不同而排列在不同的位置,如下:

// html中

<?php foreach($tree as $key=>$val) {?>

……

// js中

$('div.comm_list').css('margin-left' , 20 * lev);

复制代码

END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值