php實(shí)現(xiàn)文章評(píng)論系統(tǒng)
最近工作中需要完成一個(gè)評(píng)論的功能,上網(wǎng)查找了幾個(gè)評(píng)論系統(tǒng)的展示樣式。最后參考“多說”和“暢言”等評(píng)論系統(tǒng),自己使用PHP語言實(shí)現(xiàn)了一個(gè)簡單的評(píng)論系統(tǒng)。并記錄了兩種方式(遞歸方式和非遞歸方式)的實(shí)現(xiàn)過程,以及分析兩種方式的優(yōu)缺點(diǎn),但前端如何實(shí)現(xiàn)就沒有展現(xiàn)了。
首先設(shè)計(jì)數(shù)據(jù)庫如下:
create table `comments`( `id` bigint unsigned not null AUTO_INCREMENT, `arc_id` bigint unsigned not null COMMENT '文章id', `user_id` bigint unsigned not null COMMENT '用戶id', `comment_id` bigint unsigned not null DEFAULT '0' COMMENT '回復(fù)某個(gè)評(píng)論的id', `content` varchar(255) not null DEFAULT '' COMMENT '評(píng)論或回復(fù)的內(nèi)容', `add_time` timestamp not null DEFAULT CURRENT_TIMESTAMP COMMENT '添加時(shí)間', PRIMARY KEY (`id`), KEY `arc_id` (`arc_id`) )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '文章評(píng)論表';
創(chuàng)建測試數(shù)據(jù)如下:

具體實(shí)現(xiàn)方案如下(在ThinkPHP框架上實(shí)現(xiàn)):
1、遞歸方式
優(yōu)點(diǎn):實(shí)現(xiàn)代碼簡單,而且如果評(píng)論的層級(jí)固定在5個(gè)層次一下的話,建議使用該種方法,這樣前端通過這種數(shù)據(jù)結(jié)果實(shí)現(xiàn)簡單。
缺點(diǎn):如果評(píng)論的層級(jí)沒有固定的話,前端將無法展示評(píng)論信息了,而且如果層級(jí)太多的話,將會(huì)極大的消耗內(nèi)存,更要命的是每次遞歸都得查詢數(shù)據(jù)庫,性能將大大的降低。
/**
* @param $arc_id 文章id
* @param int $comm_id 評(píng)論id
* @param array $result
* @return array
*/
function getCommlist($arc_id, $comm_id = 0, &$result = array()){ //獲取評(píng)論列表
if(empty($arc_id)){
return array();
}
$_where = "arc_id = {$arc_id} AND comment_id = {$comm_id}";
$res = M('comments')->where($_where)->order('add_time DESC')->select();
if(empty($res)){
return array();
}
foreach ($res as $cm) {
$thisArr = &$result[];
$cm["_child"] = getCommlist($arc_id,$cm['id'],$thisArr);
$thisArr = $cm;
}
return $result;
}
部分?jǐn)?shù)據(jù)展示如下:

2、非遞歸方式(堆棧方式實(shí)現(xiàn))
優(yōu)點(diǎn):只查詢一次數(shù)據(jù)庫,性能較好??梢詫?shí)現(xiàn)n層級(jí)的評(píng)論,前端也能很好的展示
缺點(diǎn):代碼稍微復(fù)雜,對(duì)于固定的層級(jí)評(píng)論,前端展示評(píng)論較為復(fù)雜。
/**
* @param $arc_id 文章id
* @return array
*/
public function getCommlist($arc_id){
if(empty($arc_id)){
return array();
}
$res = M('comments')->where(array('arc_id'=>$arc_id))->order('add_time ASC')->select();
$dataList = $stack = array();
if($res){
foreach($res AS $k=>$v){ //先將評(píng)論的數(shù)據(jù)進(jìn)行入庫(即comment_id=0)
if($v['comment_id'] == 0){
$v['_level'] = 0; //設(shè)置層級(jí)數(shù)
$v['_root'] = $v['id']; //標(biāo)識(shí)評(píng)論id
array_push($stack,$v); //入棧
unset($res[$k]);
}
}
while(!empty($stack)){
$node = array_pop($stack); //出棧
$dataList[] = $node;
foreach($res as $_k=>$_v){
if($_v['comment_id'] == $node['id']){
$_v['_level'] = $node['_level']+1; //設(shè)置層級(jí)數(shù)
$_v['_root'] = $node['_root']; //標(biāo)識(shí)評(píng)論id
array_push($stack,$_v); //入棧
unset($res[$_k]);
}
}
}
}
return $dataList;
}
數(shù)據(jù)展示效果如下:

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
laradock環(huán)境docker-compose操作詳解
在本篇文章中小編給大家整理的是關(guān)于laradock環(huán)境docker-compose操作的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們參考學(xué)習(xí)下。2019-07-07
Zend?Framework基于Command命令行建立Zend?Framework項(xiàng)目的方法
這篇文章主要介紹了Zend?Framework基于Command命令行建立Zend?Framework項(xiàng)目的方法,較為詳細(xì)的分析了使用Command命令行建立Zend?Framework框架的具體操作步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-02-02
Zend Framework實(shí)現(xiàn)多文件上傳功能實(shí)例
這篇文章主要介紹了Zend Framework實(shí)現(xiàn)多文件上傳功能的方法,較為詳細(xì)的分析說明了Zend Framework實(shí)現(xiàn)多文件上傳的具體步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-03-03
談?wù)凱HP中substr和substring的正確用法及相關(guān)參數(shù)的介紹
這篇文章主要介紹了PHP中substr和substring的正確用法及相關(guān)參數(shù)介紹的相關(guān)資料,需要的朋友可以參考下2015-12-12
visual studio code 調(diào)試php方法(圖文詳解)
本篇文章主要介紹了visual studio code 調(diào)試php方法(圖文詳解),具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09
php設(shè)計(jì)模式之狀態(tài)模式實(shí)例分析【星際爭霸游戲案例】
這篇文章主要介紹了php設(shè)計(jì)模式之狀態(tài)模式,結(jié)合星際爭霸游戲案例形式分析了php狀態(tài)模式相關(guān)原理、使用技巧與注意事項(xiàng),需要的朋友可以參考下2020-03-03

