文章评论类,数据结构与读取方法

今天刚交付了一个项目,其中一项功能是自由评论,就是可以针对一篇文章在评论区,针对任意位置进行插入评论,类似于Laravel官网的评论区一样的功能:
文章评论类,数据结构与读取方法
文章图片

其中可以针对任何一个人进行回复.说白一点就是多叉树,类似的结构如下:
文章评论类,数据结构与读取方法
文章图片

文章的id就是根节点,每一个子节点都保存着上一级节点的id,同级节点之间使用根据创建时间进行先后排序.根据上述信息,我们的数据结构如下:
数据结构

  • id 主键
  • content 评论的内容
  • userInfo 发布该评论的用户信息.这里只拿一个字段起演示作用
  • create_time 该评论的创建时间,一定要使用int类型的时间戳,这样才好进行大小比较
  • parent_id 父级的id
  • level 级数,表示本条信息在多叉树中的第几级,主要是为了美化输出
这样的数据结构,我们就可以把上面的评论存储在数据库中了.如上面那张图片,最后的存储结果就是:
id content create_time parent_id level
1 根节点 1 0 1
2 子节点1 2 1 2
3 子节点2 3 1 2
4 子节点3 4 1 2
5 子节点4 5 4 3
6 子节点5 6 5 4
其中为了直观,create_time直接使用1,2,3,4等表示.
接下来就是如何处理从数据库中读取出来的值了.
递归读取多叉树 这里使用的语言是PHP,当然,知道什么原理的话,语言都是可以改的.首先,说一下我们最终想要获取的数据结构:
$returnData=https://www.it610.com/article/[ 0=>[ 'id'=>1, 'content'=>'子节点1' 'userinfo'=>[], 'create_time'=>1, 'parent_id'=>0, 'level'=>1 ], 1=>[ 'id'=>11, 'content'=>'子节点11' 'userinfo'=>[], 'create_time'=>11, 'parent_id'=>1, 'level'=>3 ], 2=>[ 'id'=>12, 'content'=>'子节点12' 'userinfo'=>[], 'create_time'=>12, 'parent_id'=>11, 'level'=>3 ] ];

就是将以上多叉树的结构转换成2维数组的形式,其中所有level为2,或者parent_id为0的项,表示根节点下的第一层数据,而该数据之后的项,除非也满足上述条件,否则就是该节点下的全部子节点.
为了实现上述目标,我们必须遍历该多叉树,主要就是要靠递归实现.该递归的函数的目的只有一个:
找儿子,简称找子(节点)
为了有一个全局变量存储每次遍历后的值,所以将上述方法写在一个类中:
class Family{ // 存储最后的返回结果 protected $relationship; // 存储要遍历的数据 protected $data; // 构造函数,传入要遍历的数据,并保存在全部变量中 public function __constructor($data){ $this->data=https://www.it610.com/article/$data; } /** * 递归函数,作用是获取该节点下的第一个子节点信息,并自动寻找下一个 * @param $fatherInfo array **/ protected function where_are_you_my_son($fatherInfo){ // 获取要遍历的数据 $data=$this->$data; foreach($data as $key=>$son){ /** * 如果当前项的父节点跟上一项的id一致, * 则说明当前项是上一节点的子节点, * 将其存入数组中 **/ if($son['parent_id']==$fatherInfo['id']){ $this->relationship[]=$son; // 接着找该项的子节点 $this->where_are_you_my_son($son); } // 注意,这里一定要是continue,不是break,否则只能找每个子节点的第一个子节点,而不是全部子节点 continue; } } // 调用递归函数的方法 public function findSon($rootInfo){ $this->where_are_you_my_son($rootInfo); return $this->relationship; } }

其中,findSon()函数的$rootInfo就是根节点的信息,类比上面的数据结构就是:
$rootInfo=[ 'id'=>0, 'content'=>'根节点' 'userinfo'=>[], 'create_time'=>0, 'parent_id'=>0, 'level'=>1 ];

之后就可以获取我们想要的理想数组了,其中,为了减轻后续对排序的麻烦,最好在传入操作数据之前就对其进行创建时间前后的排序,数据库的order功能可以很简单的实现这个需求.
有了该数据结构,之后如何输出数据,那就很简单了,这里就不赘述了.
这里再插一句,我个人认为是很好的办法:
【文章评论类,数据结构与读取方法】处理复杂数据之前
先设想最终呈现结果
再来慢慢向该结果靠近

    推荐阅读