thinkPHP实现基于ajax的评论回复功能


Posted in PHP onJune 22, 2018

本文实例讲述了thinkPHP实现基于ajax的评论回复功能。分享给大家供大家参考,具体如下:

控制器代码:

<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
  public function index(){
    $num = M('comment')->count(); //获取评论总数
    $this->assign('num',$num);
    $data=array();
    $data=$this->getCommlist();//获取评论列表
    $this->assign("commlist",$data);
    $this->display('index');
  }
  /**
  *添加评论
  */
  public function addComment(){
    $data=array();
    if((isset($_POST["comment"]))&&(!empty($_POST["comment"]))){
      $cm = json_decode($_POST["comment"],true);//通过第二个参数true,将json字符串转化为键值对数组
      $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();//统计评论总数
      $data['num']= $num;
    }else{
      $data["error"] = "0";
    }
    echo json_encode($data);
  }
  /**
  *递归获取评论列表
  */
  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;
  }
}

JavaScript代码:

$(function(){
  //点击提交评论内容
  $('body').delegate('.comment-submit','click',function(){
    var content = $.trim($(this).parent().prev().children("textarea").val());//根据布局结构获取当前评论内容
    $(this).parent().prev().children("textarea").val("");//获取完内容后清空输入框
    if(""==content){
      alert("评论内容不能为空!");
    }else{
      var cmdata = new Object();
      cmdata.parent_id = $(this).attr("parent_id");//上级评论id
      cmdata.content = content;
      cmdata.nickname = "游客";//测试用数据
      cmdata.head_pic = "/Public/images/default.jpg";//测试用数据
      var replyswitch = $(this).attr("replyswitch");//获取回复开关锁属性
      $.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();//删除已存在的所有回复div
            //更新评论总数
            $(".comment-num").children("span").html(data.num+"条评论");
            //显示新增评论
            var newli = "";
            if(cmdata.parent_id == "0"){
             //发表的是一级评论时,添加到一级ul列表中
             newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'><a class='comment-reply' comment_id='"+data.id+"' href='javascript:void(0);'>回复</a></div></div></div><ul class='children'></ul></li>";
              $(".comment-ul").prepend(newli);
            }else{
             //否则添加到对应的孩子ul列表中
              if('off'==replyswitch){//检验出回复关闭锁存在,即三级评论不再提供回复功能
                newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='children-cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'></div></div></div><ul class='children'></ul></li>";
              }else{//二级评论的回复按钮要添加回复关闭锁属性
                newli = "<li comment_id='"+data.id+"'><div ><div><img class='head-pic' src='"+data.head_pic+"' alt=''></div><div class='children-cm'><div class='cm-header'><span>"+data.nickname+"</span><span>"+data.create_time+"</span></div><div class='cm-content'><p>"+data.content+"</p></div><div class='cm-footer'><a class='comment-reply' comment_id='"+data.id+"' href='javascript:void(0);' replyswitch='off' >回复</a></div></div></div><ul class='children'></ul></li>";
              }
              $("li[comment_id='"+data.parent_id+"']").children("ul").prepend(newli);
            }
          }else{
            //有错误信息
            alert(data.error);
          }
        }
      });
    }
  });
  //点击"回复"按钮显示或隐藏回复输入框
  $("body").delegate(".comment-reply","click",function(){
    if($(this).next().length>0){//判断出回复div已经存在,去除掉
      $(this).next().remove();
     }else{//添加回复div
      $(".comment-reply").next().remove();//删除已存在的所有回复div
      //添加当前回复div
      var parent_id = $(this).attr("comment_id");//要回复的评论id
      var divhtml = "";
      if('off'==$(this).attr("replyswitch")){//二级评论回复后三级评论不再提供回复功能,将关闭属性附加到"提交回复"按钮"
        divhtml = "<div class='div-reply-txt' style='width:98%;padding:3px;' replyid='2'><div><textarea class='txt-reply' replyid='2' style='width: 100%; height: 60px;'></textarea></div><div style='margin-top:5px;text-align:right;'><a class='comment-submit' parent_id='"+parent_id+"' style='font-size:14px;text-decoration:none;background-color:#63B8FF;' href='javascript:void(0);' replyswitch='off' >提交回复</a></div></div>";
      }else{
        divhtml = "<div class='div-reply-txt' style='width:98%;padding:3px;' replyid='2'><div><textarea class='txt-reply' replyid='2' style='width: 100%; height: 60px;'></textarea></div><div style='margin-top:5px;text-align:right;'><a class='comment-submit' parent_id='"+parent_id+"' style='font-size:14px;text-decoration:none;background-color:#63B8FF;' href='javascript:void(0);'>提交回复</a></div></div>";
      }
      $(this).after(divhtml);
     }
  });
})

页面样式代码:

.comment-filed{
  width:640px;
  margin:0 auto;
}
.comment-num{
  text-align: right;
  font-size:14px;
}
.div-txt-submit{
  text-align:right;
  margin-top:8px;
}
.comment-submit{
  background-color:#63B8FF;
  margin-top:15px;
  text-decoration:none;
  color:#fff;
  padding:5px;
  font-size:14px;
}
.txt-commit{
  border:1px solid blue;
  width:620px;
  height: 60px;
  padding: 10px;
}
.txt-reply{
  width: 100%;
  height: 60px;
}
.comment-filed-list{
  margin-top:20px;
}
.comment-list{
  margin-top:2px;
  width:herit;
  height:50px;
  border-top:1px solid gray;
}
.comment-ul{
  list-style:none;
  padding-left:0;
}
.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;
}
.children{
  list-style:none;
  background-color:#FAFAFA;
  padding-left:0;
  margin-left:40px;
}
.children-cm{
  position:relative;
  left:40px;
  top:-40px;
  width:90%;
}

页面布局代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  <title>php评论及回复功能</title>
  <link rel="stylesheet" type="text/css" href="/Public/css/comment.css" rel="external nofollow" >
  <script type="text/javascript" src="/Public/js/jquery-1.11.3.min.js" ></script>
  <script type="text/javascript" src="/Public/js/comment.js" ></script>
</head>
<body>
<div class="comment-filed">
 <!--发表评论区begin-->
 <div>
  <div class="comment-num">
    <span>{$num}条评论</span>
  </div>
  <div>
    <div>
    <textarea class="txt-commit" replyid="0"></textarea>
    </div>
    <div class="div-txt-submit">
      <a class="comment-submit" parent_id="0" style="" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" ><span style=''>发表评论</span></a>
    </div>
  </div>
 </div>
 <!--发表评论区end-->
 <!--评论列表显示区begin-->
  <!-- {$commentlist} -->
  <div class="comment-filed-list" >
    <div><span>全部评论</span></div>
    <div class="comment-list" >
      <!--一级评论列表begin-->
      <ul class="comment-ul">
        <volist name="commlist" id="data">
          <li comment_id="{$data.id}">
          <div >
            <div>
              <img class="head-pic" src="{$data.head_pic}" alt="">
            </div>
            <div class="cm">
              <div class="cm-header">
              <span>{$data.nickname}</span>
              <span>{$data.create_time}</span>
              </div>
              <div class="cm-content">
                <p>
                  {$data.content}
                </p>
              </div>
              <div class="cm-footer">
                <a class="comment-reply" comment_id="{$data.id}" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a>
              </div>
            </div>
          </div>
          <!--二级评论begin-->
          <ul class="children">
            <volist name="data.children" id="child" >
            <li comment_id="{$child.id}">
              <div >
                <div>
                  <img class="head-pic" src="{$child.head_pic}" alt="">
                </div>
                <div class="children-cm">
                  <div class="cm-header">
                  <span>{$child.nickname}</span>
                  <span>{$child.create_time}</span>
                  </div>
                  <div class="cm-content">
                    <p>
                      {$child.content}
                    </p>
                  </div>
                  <div class="cm-footer">
                    <a class="comment-reply" replyswitch="off" comment_id="{$child.id}" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a>
                  </div>
                </div>
              </div>
              <!--三级评论begin-->
              <ul class="children">
                <volist name="child.children" id="grandson" >
                <li comment_id="{$grandson.id}">
                  <div >
                    <div>
                      <img class="head-pic" src="{$grandson.head_pic}" alt="">
                    </div>
                    <div class="children-cm">
                      <div class="cm-header">
                      <span>{$grandson.nickname}</span>
                      <span>{$grandson.create_time}</span>
                      </div>
                      <div class="cm-content">
                        <p>
                          {$grandson.content}
                        </p>
                      </div>
                      <div class="cm-footer">
                        <!-- <a class="comment-reply" comment_id="1" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >回复</a> -->
                      </div>
                    </div>
                  </div>
                </li>
                </volist>
              </ul>
              <!--三级评论end-->
            </li>
            </volist>
          </ul>
          <!--二级评论end-->
        </li>
        </volist>
      </ul>
      <!--一级评论列表end-->
    </div>
  </div>
 <!--评论列表显示区end-->
</div>
</body>
</html>

sql语句:

DROP TABLE IF EXISTS `t_comment`;
CREATE TABLE `t_comment` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
 `parent_id` int(11) NOT NULL COMMENT '上级评论id,若是一级评论则为0',
 `nickname` varchar(100) DEFAULT NULL COMMENT '评论人昵称',
 `head_pic` varchar(400) DEFAULT NULL COMMENT '评论人头像',
 `content` text COMMENT '评论内容',
 `create_time` datetime DEFAULT NULL COMMENT '评论或回复发表时间',
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=148 DEFAULT CHARSET=utf8;

页面布局少一个jquery.js请自行加上。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
使用PHP遍历文件夹与子目录的函数代码
Sep 26 PHP
PHP计算一年多少个星期和每周的开始和结束日期
Jul 01 PHP
修改destoon会员公司的伪静态中的com目录的方法
Aug 21 PHP
PHP获取一段文本显示点阵宽度和高度的方法
Mar 12 PHP
php实现递归的三种基本方式
Jul 04 PHP
PHP实现清除wordpress里恶意代码
Oct 21 PHP
php实现三级级联下拉框
Apr 17 PHP
php根据年月获取当月天数及日期数组的方法
Nov 30 PHP
thinkPHP模板引擎用法示例
Dec 08 PHP
php 基础函数
Feb 10 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
Jul 21 PHP
PHP代码加密的方法总结
Mar 13 PHP
php strftime函数的详细用法
Jun 21 #PHP
PHP获取本周所有日期或者最近七天所有日期的方法
Jun 20 #PHP
ThinkPHP5.0 图片上传生成缩略图实例代码说明
Jun 20 #PHP
thinkPHP框架实现的短信接口验证码功能示例
Jun 20 #PHP
thinkPHP3.2.2框架行为扩展及demo示例
Jun 19 #PHP
Laravel框架实现的记录SQL日志功能示例
Jun 19 #PHP
PHP 中 var_export、print_r、var_dump 调试中的区别
Jun 19 #PHP
You might like
php echo 输出字符串函数详解
2010/05/13 PHP
Codeigniter生成Excel文档的简单方法
2014/06/12 PHP
PHP原生函数一定好吗?
2014/12/08 PHP
标准PHP的AES加密算法类
2015/03/12 PHP
php超快高效率统计大文件行数
2015/07/05 PHP
前端必学之PHP语法基础
2016/01/01 PHP
CentOS下搭建PHP环境与WordPress博客程序的全流程总结
2016/05/07 PHP
jquery 图片预加载 自动等比例缩放插件
2008/12/25 Javascript
Javascript的构造函数和constructor属性
2010/01/09 Javascript
原生JS实现表单checkbook获取已选择的值
2013/07/21 Javascript
JS获取网页属性包括宽、高等等
2014/04/03 Javascript
浅谈JS之tagNaem和nodeName
2016/09/13 Javascript
Node.js实现发送邮件功能
2017/11/06 Javascript
基于vue-upload-component封装一个图片上传组件的示例
2018/10/16 Javascript
刷新页面后让控制台的js代码继续执行
2019/09/20 Javascript
Vue利用Blob下载原生二进制数组文件
2019/09/25 Javascript
基于vue-draggable 实现三级拖动排序效果
2020/01/10 Javascript
微信小程序间使用navigator跳转传值问题实例分析
2020/03/27 Javascript
利用Python的Django框架中的ORM建立查询API
2015/04/20 Python
Python 实现 贪吃蛇大作战 代码分享
2016/09/07 Python
详解Python的Lambda函数与排序
2016/10/25 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
使用pandas模块读取csv文件和excel表格,并用matplotlib画图的方法
2018/06/22 Python
python的内存管理和垃圾回收机制详解
2019/05/18 Python
Python箱型图处理离群点的例子
2019/12/09 Python
python中实现词云图的示例
2020/12/19 Python
Python爬虫实例之2021猫眼票房字体加密反爬策略(粗略版)
2021/02/22 Python
Html5 new XMLHttpRequest()监听附件上传进度
2021/01/14 HTML / CSS
三陽商会官方网站:Sanyo iStore
2019/05/15 全球购物
Agoda中文官网:安可达(低价预订全球酒店)
2021/01/18 全球购物
大学生学业生涯规划
2014/01/05 职场文书
优秀社区干部事迹材料
2014/02/03 职场文书
英语教师求职信
2014/06/16 职场文书
公司规章制度范本
2015/08/03 职场文书
php远程请求CURL案例(爬虫、保存登录状态)
2021/04/01 PHP
关于Nginx中虚拟主机的一些冷门知识小结
2022/03/03 Servers