我的畢設專案的評論模組原來是採用多說外掛程式完成的,但是我現在希望能夠自己管理評論內容,所以我自己開始寫評論模組。具體準備採用與下評論類似的結構,即一級評論直接顯示在文章下方,而二三級評論顯示在一級評論的下方,如下圖所示:
我覺得這可以說是無限極分類的一種運用,準確的說是子孫樹的運用,進行子孫樹分類後,循環輸出內容,形成評論(不懂無限極分類的朋友可以去看看我的文章無限極分類原理與實現)。
當然,真正完成無限極回評論的功能還有其他的要點,以下就來說說我是怎麼完成無限極評論的。
首先,就是資料表的設計。如果是論壇系統,可以將評論的資料分割成兩個表,一個表格儲存評論的訊息,包括發佈貼文的使用者id或回覆的使用者id,回覆的貼文id,回覆的時間等;另一個表,儲存評論的內容,包括貼文的主題和回覆的內容。
我完成的是文章的評論模組,就沒分成兩個表了,直接將評論的內容與資訊放在一起,如下面結構:
列名 | 列型別 | 列屬性 | #說明 |
---|---|---|---|
comm_id | |||
UNSIGNED PRIMARY | KEY | AUTO_INCREMENT主鍵 | #user_id |
UNSIGNED NOT | NULL | DEFAULT 0#使用者id | |
#INT | UNSIGNED NOT NULL DEFAULT 0 | 評論的父級 | |
INT | #UNSIGNED NOT NULL DEFAULT 0 |
評論的文章id |
|
#TEXT | 評論的內容 | comm_time |
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中,同樣能完成評論模組。但是,這種結構是很雜亂,而且無序的。要完成如評論一樣的評論模組,就得採用特殊的方式。
那麼,就要好好觀察一下評論的結構了。
結合上面的資料表結構,可以推論一下,從資料表中取出且無限極分類後的數據,它的結構應該是這樣的:
array ( array(一级评论, child=>array( 二级评论, 三级评论 ) ), array ( 一级评论 , child=>array( ) ……
為什麼這麼說?你可以很明顯的看出,二級、三級評論被包裹在一級評論中,而二級、三級評論是平行關係;因此,二級、三級評論是一級評論的子孫節點,而二級、三級評論是平行節點,不存在父子關係。
因此,可以得出,分類後的數據有且只有一個子孫節點,多級評論無論是不是對一級評論進行回复,只要是處於一級評論的範圍,那麼它的父節點必然是一級評論。
那麼,二級、三級回覆中的@某某某
又是怎麼實現的?其實,我在這裡困擾了很久。我期望用對錶的自身連接來完成,但是不行,破壞了上面所述的結構。最後,我從請求的json資料中得到了答案,請看評論的json資料:
上傳後面有點模糊,各位同學可以藉助火狐或谷歌瀏覽器上面的插件觀察JSON資料。
重點觀察compiled_content字段,可以推斷它是將
@某某某直接儲存到資料庫中的。這樣問題就解決了,同時觀察json數據,也能夠驗證我上面所述的結構是正確的。
// replyUser 即 被回复的用户名 @xxxx var content = $('#reply').val.split(replyUser)[1]; var userlink = '<a href="#" class="xxx" target="_blank" >' + replyUser + '</a>'; var comm_cont = encodeURIComponent(userlink+content);
函數如下:
/** * @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; }
<?php foreach($tree as $key=>$val) ?> <p class="comm_list" > <h2><?php echo $val['user_name'];?></h2> <p><?php echo $val['comm_cont'] ?></p> <!-- 其他信息 --> <p class="comm_reply"> <?php if(!empty($val['child'])) { ?> <?php foreach($val['child'] as $k=>$v) ?> <p class="reply_list" > <h2><?php echo $v['user_name'];?></h2> <p><?php echo $v['comm_cont'] ?></p> <!-- 其他信息 --> </p> <?php }}?> </p> </p> <?php } ?>
PS
這只是評論的一種形式,如還有一種類別樓梯式的結構,這種實作則更為簡單一點,如下圖:/** * 子孙树 */ 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; }
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) {?> <p class="comm_list" lev="<?php echo $val['lev']?>"> …… </p> <?php } ?> // js中 $('p.comm_list').css('margin-left' , 20 * lev);
以上是PHP:打造一個無限極評論模組的詳細內容。更多資訊請關注PHP中文網其他相關文章!