Php unlimited classification practices-comment and reply functions
The comment function is often seen below the details pages of major forums or news sections. Of course, it is not just as simple as directly posting comments, and you can reply to others' comments, others can review or reply to your reply again. In theory, there is no limit. From a technical point of view, it is easy to think of using the unlimited classification technology to store data, use recursion to obtain comment-level structure data and ajax to implement comment-page interaction. Here we use thinkphp framework as a simple demo trainer. In order to simplify the process, Level 3 comments no longer provide the reply function, of course, you only need to make a slight modification on this basis to implement the unlimited reply function, mainly because it takes some time to modify the view layer style. I. Performance Requirement Analysis:
You can directly publish a level-1 comment in the header. The latest comment is shown at the top, as shown below:
You can reply to a published comment. The reply is displayed below the comment, forming a hierarchical relationship, as shown below:
Page Operation Details: When you click the reply button of a comment, the reply text input box is displayed, and the reply text input box of other comments disappears. When you click the reply button again, the text box disappears.
Disable the reply function in the last-level comment (set to level 3 here ).
Display comments in real time II. Implementation ideas and details 1. Data Table Design
2. Key functions at the controller layer:
(1). recursively retrieve the comment list
/*** Recursively retrieve the comment list */protected function getCommlist ($ parent_id = 0, & $ result = array () {$ arr = M ('comment ') -> where (parent_id = '. $ parent_id. ')-> order (create_time desc)-> select (); if (empty ($ arr) {return array ();} foreach ($ arr as $ cm) {$ thisArr = & $ result []; $ cm [children] = $ this-> getCommlist ($ cm [id], $ thisArr); $ thisArr = $ cm ;} return $ result ;}
(2). display the action on the comment page
Public function index () {$ num = M ('comment')-> count (); // gets the total number of comments $ this-> assign ('num', $ num ); $ data = array (); $ data = $ this-> getCommlist (); // get the comment list $ this-> assign (commlist, $ data ); $ this-> display ('index ');}
(3). ajax access to the comment page to add the comment action
/*** Add comments */public function addComment () {$ data = array (); if (isset ($ _ POST [comment]) & (! Empty ($ _ POST [comment]) {$ cm = json_decode ($ _ POST [comment], true); // use the second parameter true, convert a json string to a key-Value Pair array $ cm ['create _ time'] = date ('Y-m-d H: I: s', time ()); $ newcm = M ('comment'); $ id = $ newcm-> add ($ cm); $ cm [id] = $ id; $ data = $ cm; $ num = M ('comment')-> count (); // count the total number of comments $ data ['num'] = $ num ;} else {$ data [error] = 0;} echo json_encode ($ data );}
3. view layer implementation
(1) display the overall structure design of the page
Actual results:
Page html code:
<Script type = text/javascript src =/Public/js/jquery-1.11.3.min.js> </script> <script type = text/javascript src =/Public/js/comment. js> </script>
{$ Num} comments
Post comments
All comments
{$data.nickname} {$data.create_time}
{$data.content}
Reply
{$child.nickname} {$child.create_time}
{$child.content}
Reply
{$grandson.nickname} {$grandson.create_time}
{$grandson.content}
-
-
-
-
-
-
(2) div structure code of a single comment
{$data.nickname} {$data.create_time}
{$data.content}
Reply
Corresponding:
Corresponding css code:
.head-pic{ width:40px; height:40px; }.cm{ position:relative; top:0px; left:40px; top:-40px; width:600px;}.cm-header{ padding-left:5px;}.cm-content{ padding-left:5px;}.cm-footer{ padding-bottom:15px; text-align:right; border-bottom: 1px dotted #CCC;}.comment-reply{ text-decoration:none; color:gray; font-size: 14px;}
4. JS Code
(1). submit comments: the tag button for the comments references the style comment-submit and performs ajax operations in the click event.
$ ('Body '). delegate ('. comment-submit ', 'click', function () {var content = $. trim ($ (this ). parent (). prev (). children (textarea ). val (); // get the current Comment content based on the layout structure $ (this ). parent (). prev (). children (textarea ). val (); // after obtaining the content, clear the input box if (= content) {alert (the comment content cannot be blank !);} Else {var cmdata = new Object (); cmdata. parent_id = $ (this ). attr (parent_id); // The comment id cmdata. content = content; cmdata. nickname = tourist; // test data cmdata. head_pic =/Public/images/default.jpg; // var replyswitch = $ (this ). attr (replyswitch); // get the reply Switch Lock attribute $. ajax ({type: POST, url:/index. php/home/index/addComment, data: {comment: JSON. stringify (cmdata)}, dataType: json, success: function (data) {if (typeof (data. error) = undefined) {$ (. comment-reply ). next (). remove (); // delete all existing reply divs // update the total number of comments (.comment-num=.children(span=.html (data. num + Comments); // displays the newly added comments var newli =; if (cmdata. parent_id = 0) {// when a level-1 comment is published, newli = is added to the level-1 ul list.
+data.nickname++data.create_time+
+data.content+
Reply
; $ (. Comment-ul ). prepend (newli);} else {// otherwise, add it to the child ul list if ('off' = replyswitch) {// check whether the reply lock exists, that is, Level 3 comments no longer provide the reply function newli =
+data.nickname++data.create_time+
+data.content+
;} Else {// The reply button of the second-level comment to add the reply lock attribute newli =
+data.nickname++data.create_time+
+data.content+
Reply
;} $ (Li [comment_id = '+ data. parent_id + ']). children (ul ). prepend (newli) ;}} else {// error message alert (data. error );}}});}});
(2). reply to the comment: the tag button of the reply comment references the style comment-reply to show or hide the comment input box in the click event.
// Click the reply button to display or hide the reply input box $ (body ). delegate (. comment-reply, click, function () {if ($ (this ). next (). length> 0) {// determine whether the reply div already exists and remove $ (this ). next (). remove ();} else {// Add reply div $ (. comment-reply ). next (). remove (); // delete all existing reply div. // Add the current reply div var parent_id =$ (this ). attr (comment_id); // comment id var divhtml =; if ('off' = $ (this ). attr (replyswitch) {// after the second-level comments reply, the third-level comments no longer provide the reply function. Attach the closed attribute to the submit reply button divhtml =
Submit a reply
; }else{ divhtml =
Submit a reply
; } $(this).after(divhtml); } });